Create a custom manager and migrate to nvim

I've migrated to Neovim because of one thing... Luke Smith-senpai...

Ever since I've seen him typed 'nvim' in his recent videos, I was devastated. All of those hours that my little heart and soul poured into creating a 130-line vimrc to configure Vim to its absolute in the way I wanted to use was gone. All of those 7 days and a few minutes every now and then, are crushed.

It is truly a betrayal to see it use a modernized version of a relic of the past. I first thought, "How dare he?". I was not able to sleep well the following days. It was heart-wrenching.

Out of spite, I've tried to. I've nothing left and you know there is a saying 'a weeb with nothing got nothing to lose'. All it took was to rename certain files, reinstall the plugin manager and its plugins, a grand total of 5 minutes. My heart skipped a beat.

It was like being a birb with broken wings trying to fly and eventually didn't left off until its talon is in the ground. And the ground is Neovim. Now I love Neovim more than ever... Thank you Luke Smith Unaboomer-kun-senpai. It was truly a wonderful experience.
This commit is contained in:
foo-dogsquared 2020-03-29 20:23:44 +08:00
parent c72d63e12e
commit e5222304a1
14 changed files with 416 additions and 51 deletions

View File

@ -53,13 +53,9 @@ Here are the main specifications of my machine currently running this (as of 201
* **Window manager**: https://github.com/baskerville/bspwm[bspwm]
* **Terminal emulator**: https://github.com/jwilm/alacritty/[Alacritty]
* **Shell**: http://www.zsh.org/[Zsh]
* **Terminal emulator font**: https://github.com/be5invis/iosevka[Iosevka] (with the https://github.com/ryanoasis/nerd-fonts[Nerd Font patches])
* **Terminal emulator font**: https://github.com/be5invis/iosevka[Iosevka]
* **GTK theme**: https://github.com/horst3180/Arc-theme[Arc theme] (Arc Darker variant)
Terminal color scheme was generated with https://github.com/dylanaraps/pywal[pywal].
The picture is used to generate the color pallete is https://www.reddit.com/r/wallpapers/comments/cckpj0/i_made_this_simple_and_clean_drawing_over_the/[this one].
It's also the wallpaper used in the screenshots.
@ -68,21 +64,24 @@ It's also the wallpaper used in the screenshots.
Here's a list of the wallpapers I've used throughout my ricing journey.
I've also tried to get the creators to show appreciation for their work.
* https://www.reddit.com/r/wallpapers/comments/ed99q8/alien_moon_rmradev/[`alien-moon.jpg`]
* https://www.deviantart.com/rmradev/art/Alien-Moon-743912901[`alien-moon.jpg`]
** Creator: https://www.deviantart.com/rmradev[rmRadev]
** Original link: https://www.deviantart.com/rmradev/art/Alien-Moon-743912901
* https://www.reddit.com/r/wallpapers/comments/edn0ju/4k_desktop_wallpaper/[`forest-bright.jpg`]
** Creator: https://dribbble.com/MikaelGustafsson[Mikael Gustafsson]
** Original link: https://dribbble.com/shots/3713646-Small-Memory
* https://dribbble.com/shots/3713646-Small-Memory[`forest-bright.jpg`]
** Creator: https://dribbble.com/MikaelGustafsson[Mikael Gustafsson]
* https://www.reddit.com/r/wallpapers/comments/efkxb5/hotline_miami_alternate_cover_iv_by_mbdsgns/[`hotline-miami-alt-cover.png`]
* https://dropr.com/mbdsgns/254740/hotline_miami_iv/+?p=1388845[`hotline-miami-alt-cover.png`]
** Creator: https://dropr.com/mbdsgns[Mbdsgns]
** Original link: https://dropr.com/mbdsgns/254740/hotline_miami_iv/+?p=1388845
* https://www.artstation.com/artwork/wn8ng[`long-walk-home.jpg`]
** Creator: https://www.artstation.com/beaulamb[Beau Lamb]
* https://www.reddit.com/r/wallpapers/comments/cckpj0/i_made_this_simple_and_clean_drawing_over_the/[`nebula.jpg`]
** Creator: https://www.reddit.com/user/datGryphon/[datGryphon]
* https://www.artstation.com/artwork/XOQdR[`the-core.jpg`]
** Creator: https://www.artstation.com/beaulamb[Beau Lamb]
* https://www.reddit.com/r/wallpapers/comments/ebvk0q/rocket_launch_1920x1080/[`rocket-launch.jpg`]
* https://www.reddit.com/r/wallpapers/comments/co9t14/sand/[`sand.jpg`]
@ -96,28 +95,60 @@ There are a few things to know on this setup.
* `packages.txt` is mainly for archiving my native package list from the official Arch Linux repos installed in my current Arch Linux setup.
* `aur-packages.txt` contains the installed packages from AUR along with their versions.
* `locations.json` is a data file that contains all of the packages listed in <<Configured programs>> along with their target path.
* `manager.py` is a little manager tailored for this setup.
* A makefile (named `makefile`) which makes use of GNU Make.
Both of the above files are going to be committed at the start of every month.
`packages.txt` and `aur-packages.txt` are simply a list of installed packages from the official Arch repo and AUR respectively.
They are going to be committed at the start of every month (if it works that is).
My own scripts is in link:bin/[`bin/`].
`manager.py` is a tiny https://www.gnu.org/software/stow/[GNU Stow]-inspired manager created for this setup.
(Nonetheless, I tried to make it generic for other cases.)
It takes a directory with a file named `locations.json` containing the packages with their target path.
We can then execute commands with all of the packages and its target path.
footnote:[Obviously, you need Python installed for this.
For future references, the version by the time first writing the script is at v3.8.1.]
[source, shell]
----
# Take the setup as the filesystem structure.
# See the JSON file (locations.json) to see what packages to be installed and where to install them.
# Running the program without any arguments for a test run.
# There should be a bunch of `echo` commands being ran for all of the listed packages.
./manager.py
# Create the directories of the target path and install them with GNU Stow.
# Bada-bing, bada-boom, you have installed your setup or something.
./manager.py --commands "mkdir -p {location}" "stow --restow {package} --target {location}"
----
Just execute the script with the `--help` flag for more information. ;p
Next, more custom scripts.
They're located in link:bin/[`bin/`] and ideally should be linked in `$PATH`.
Currently, I have them linked in `$HOME/bin`.
Ideally, the linked path should be included as part of the `$PATH` environment variable.
This is mostly used with hotkey bindings (e.g., `sxhkd`).
The scripts are mostly used with hotkey bindings (e.g., `sxhkd`).
Nonetheless, they could be executed in the shell (provided they are linked in `$PATH`).
Here's the list of primary scripts:
Here's a list of the top most useful scripts:
* Screenshot capture.
* link:./bin/screenshot[Screenshot capture].
Includes the option of delaying and region selection mode.
* Screen recording.
* link:./bin/ocr[An image-to-text script using OCR].
The content are then copied into the clipboard.
Built on top of the screenshot script.
Useful for capturing links in images or videos.
* link:./bin/record[Screen recording] using https://ffmpeg.org/[FFmpeg].
An option of excluding and/or following the mouse cursor is included.
* Quick command prompts.
* link:./bin/prompt[Quick command prompts].
The script is based from https://github.com/LukeSmithxyz/voidrice/blob/master/.local/bin/prompt[Luke Smith's prompt script].
* Switching on/off programs.
* link:./bin/toggle-bin[Switching on/off programs].
Useful for situations where only one instance of the program is running.
Aside from the scripts, there are also some details and files that are not committed to this setup for privacy and security reasons.
@ -247,16 +278,18 @@ For documentation, check out the manual entry (i.e., `man picom`) and the https:
The default configuration (located at `/etc/xdg/picom.conf` assuming at Arch Linux) can be helpful as well as it is filled with comments.
=== https://www.vim.org/[Vim]
=== https://neovim.io/[Neovim]
A modal text editor.
A modern version of https://www.vim.org/[Vim], a modal text editor.
footnote:[Migrated after I've seen https://lukesmith.xyz/[Luke-senpai] used it in his recent videos.
Seriously though, I find nvim to be way better for configuration.]
* Config located at link:vim/[`vim/`] directory.
* The usual target path for a user is at `$HOME/`.
* Minimum version (from `vim --version`):
** `8.1 (2018 May 18, compiled Jul 29 2019 20:38:53)`
* Config located at link:nvim/[`nvim/`] directory.
* The usual target path for a user is at `$HOME/.config/nvim`.
* Minimum version (from `nvim --version`):
** `NVIM v0.4.3`
* Uses https://github.com/junegunn/vim-plug[`vim-plug`] as the plugin manager.
* Contains my plugin list and editor configurations at `.vimrc`.
* Contains my plugin list and editor configurations in `init.vim`.
* There are also some https://github.com/sirver/UltiSnips[UltiSnips] snippets stored in `own-snippets` folder (since `snippets` is a reserved folder name).
* One of the largest snippet file is the snippets for LaTeX files.
It is based on https://github.com/gillescastel/latex-snippets/[_Gilles Castel_'s UltiSnips LaTeX snippets].
@ -328,7 +361,7 @@ The target path is more lenient since it only contains data files.
You have more choices here.
* Minimum version (from `wal -v`):
** `wal 3.3.0`
* The folder only contains a bunch of themes in JSON files.
* The folder only contains the best of the themes in JSON files.
All of the data files are named after the filenames of the wallpapers.
A few of them are listed in the <<Wallpapers>> section for the sources.
The JSON files does need a little bit of tweaking especially with the `wallpaper` key.
@ -386,8 +419,8 @@ I also have to use the https://www.archlinux.org/packages/extra/x86_64/nvidia-39
* https://audacious-media-player.org/[Audacious] - An audio player with various listening options.
* https://ffmpeg.org/[ffmpeg] - A multimedia codec including for MP4, FLV, and more.
* https://www.imagemagick.org/[ImageMagick] - A software suite for graphics.
Also can be used as a recorder.
* https://www.imagemagick.org/[ImageMagick] - A software suite for graphics.
* https://obsproject.com/[OBS Studio] - A facility for streaming and recording videos.
* https://www.shotcut.org/[Shotcut] - A video editor built with the https://www.mltframework.org/[MLT Framework].
* https://www.videolan.org/vlc/[VLC Media Player] - A multimedia player.

15
locations.json Normal file
View File

@ -0,0 +1,15 @@
{
"alacritty": "$HOME/.config/alacritty/",
"bin": "$HOME/bin/",
"bspwm": "$HOME/.config/bspwm/",
"dunst": "$HOME/.config/dunst/",
"nvim": "$HOME/.config/nvim/",
"picom": "$HOME/.config/picom",
"polybar": "$HOME/.config/polybar",
"ranger": "$HOME/.config/ranger/",
"rofi": "$HOME/.config/rofi/",
"sxhkd": "$HOME/.config/sxhkd/",
"wal": "$HOME/.local/share/wal",
"xorg": "$HOME",
"zsh": "$HOME"
}

11
makefile Normal file
View File

@ -0,0 +1,11 @@
.PHONY = install
install:
./manager.py --commands "mkdir -p {location}" "stow --stow {package} --target {location}"
.PHONY = reinstall
reinstall:
./manager.py --commands "mkdir -p {location}" "stow --restow {package} --target {location}"
.PHONY = clean
clean:
./manager.py --commands "stow --delete {package} --target {location}"

197
manager.py Normal file
View File

@ -0,0 +1,197 @@
#!/usr/bin/env python
# A simple setup script for the packages.
# There should be a file named `locations.json` in this setup where it contains a top-level hash map with the packages and their target path.
# Feel free to modify it accordingly.
# This script is tailored to my specific needs.
# It also strives to only rely on the standard library so further no installation needed.
# Feel free to modify this script as well.
# For future references, the Python version when creating for this script is v3.8.2.
# If there's any reason why stuff is not working, it might be because it is different on the older versions or just my bad code lol.
# Anyway, I feel like this script should be only up to half the size.
# Hell, I think this should be simpler but no... I pushed for a more complex setup or something.
# What am I doing?
# Is this what ricing is all about?
# Why are you reading this?
import argparse
import json
import logging
import os
import os.path
from pathlib import Path
import subprocess
import sys
PACKAGE_DATA_FILE="locations.json"
class PackageDir:
""" A package directory should have a file named `locations.json` where it contains a top-level object of the stow packages with their usual target path. """
def __init__(self, package_path = None):
"""
Creates an instance of PackageDir
:param: package_path - The directory where it should contain a file named `locations.json`.
"""
if package_path is None:
package_path = os.getcwd()
package_path = Path(package_path)
self.path = package_path
# Loads the packages
self.packages = {}
try:
self.load_packages()
except:
pass
def add_package(self, package, target):
"""
Add the package to the list.
:param: package - the name of the package
:param: target - the target path of the package
"""
package_path = self.path / package
assert package_path.is_dir(), f"The given package '{package}' does not exist in the package directory."
self.packages[package] = target
def remove_package(self, package):
"""
Remove the package in the list.
Although this function is quite simple, this is only meant as an official API.
:param: package - the package to be removed
"""
return self.packages.pop(package, None)
def load_packages(self):
"""
Loads the packages from the data file.
"""
assert self.json_location.is_file(), "There is no 'package.json` in the given directory."
with open(self.json_location) as f:
package_map = json.load(f)
for package, target in package_map.items():
try:
self.add_package(package, target)
except Exception as e:
logging.error(e)
def execute_packages(self, commands):
"""
Execute a set of commands with the packages.
:param: commands - A list of strings that'll be used as a template.
The template string uses the `string.format` syntax.
(https://docs.python.org/3/library/string.html?highlight=template#format-string-syntax)
It should contain a binding to the keywords `package` and `location` (e.g., `stow --restow {package} --target {location}`).
"""
for package, location in self.packages.items():
# Making sure the location is expanded.
location = os.path.expanduser(location)
target_cwd = os.path.realpath(self.path)
for command in commands:
command = command.format(package=package, location=location)
process_status = subprocess.run(command, cwd=target_cwd, capture_output=True, shell=True, encoding='utf-8')
if process_status.returncode == 0:
logging.info(f"{command}: successfully ran")
else:
logging.error(process_status.stderr.strip())
@property
def json_location(self):
""" Simply appends the path with the required JSON file. """
return self.path / PACKAGE_DATA_FILE
def setup_logging():
"""
Setup the logger instance.
"""
logging.basicConfig(format="[%(levelname)s] %(module)s: %(message)s", level=logging.INFO, stream=sys.stdout)
def setup_args():
"""
Setup the argument parser.
:returns: An ArgumentParser object.
"""
description = """A quick installation script for this setup. Take note this is tailored to my specific needs."""
argparser = argparse.ArgumentParser(description=description)
argparser.add_argument("-c", "--commands", metavar = "command", help = "Executing the specified commands. All of the commands are treated as they were entered in the shell.", nargs = "*", default = ["echo {package}"])
argparser.add_argument("-d", "--directory", metavar = "path", help = "Set the directory of the package data file.", type = Path, nargs = "?", default = Path(os.getcwd()))
argparser.add_argument("--exclude", metavar = "package", help = "Exclude the given packages.", type = str, nargs = "+", default = [])
argparser.add_argument("--include", metavar = ("package", "location"), help = "Include with the following packages.", type = str, nargs = 2, action = "append", default = [])
argparser.add_argument("--only", metavar = "package", help = "Only execute with the given packages.", type = str, nargs = "+", default = [])
return argparser
def parse_args(parser, argv):
"""
Parse the arguments.
This is also the main function to pay attention to.
:param: parser - An instance of the argument parser.
:param: argv - A list of arguments to be parsed.
"""
args = parser.parse_args(argv)
try:
package_dir = PackageDir(args.directory)
# Include the following packages.
for package, target in args.include:
try:
package_dir.add_package(package, target)
except Exception as e:
logging.error(e)
# Exclude the following packages.
# We don't need the value here so we'll let it pass.
for package in args.exclude:
package_dir.remove_package(package)
if len(args.only) >= 1:
items = {}
for package in args.only:
value = package_dir.remove_package(package)
if value is None:
continue
items[package] = value
package_dir.packages.clear()
package_dir.packages = items
# Execute the commands with the packages.
package_dir.execute_packages(args.commands)
except Exception as e:
logging.error(e)
if __name__ == "__main__":
setup_logging()
argparser = setup_args()
parse_args(argparser, sys.argv[1:])

View File

@ -1,14 +1,24 @@
" plugin list (using vim-plug)
call plug#begin('~/.vim/plugged')
" Plugin list (using vim-plug).
" Activate it with ':PlugInstall' for the first time.
call plug#begin('~/.config/nvim/plugged')
Plug 'sirver/ultisnips'
" setting my private snippets in a consistent home directory
let g:UltiSnipsSnippetDirectories = [$HOME . "/.vim/own-snippets"]
" Setting my private snippets in a consistent home directory
let g:UltiSnipsSnippetDirectories = [$HOME . "/.config/nvim/own-snippets", "own-snippets"]
let g:UltiSnipsExpandTrigger="<tab>"
let g:UltiSnipsJumpForwardTrigger="<tab>"
let g:UltiSnipsJumpBackwardTrigger="<s-tab>"
let g:UltiSnipsEditSplit="context"
if has('nvim')
Plug 'Shougo/deoplete.nvim', { 'do': ':UpdateRemotePlugins' }
else
Plug 'Shougo/deoplete.nvim'
Plug 'roxma/nvim-yarp'
Plug 'roxma/vim-hug-neovim-rpc'
endif
let g:deoplete#enable_at_startup = 1
Plug 'scrooloose/nerdtree'
Plug 'honza/vim-snippets'
@ -53,24 +63,25 @@ Plug 'airblade/vim-gitgutter'
call plug#end()
" quick escape to default mode
" Quick escape to default mode.
inoremap jk <Esc>
" editor configurations
" setting number lines in the gutter
" Editor configurations:
" Setting number lines in the gutter.
set number relativenumber
" setting line highlighting based on the position of the cursor
" Setting line highlighting based on the position of the cursor.
set cursorline
" set tab to enter spaces, instead
" Set tab to enter spaces, instead.
set expandtab
" set entering tab to 4 spaces
" Set entering tab to 4 spaces.
set shiftwidth=4 tabstop=4
" The template list is simply an array composed of vector that represents the
" prefix and the suffix of the template file name
" prefix and the suffix of the template file name.
let template_list = [
\ ["_minted-", ""],
\ ["", ".synctex"],
@ -88,7 +99,7 @@ function VimtexAdditionalCleanup(template_list)
endfor
endfunction
" initiate LaTeX file compilation at the start and auto clean up
" Initiate LaTeX file compilation at the start and auto clean up.
augroup vimtex_events
au!
" auto-clean
@ -97,17 +108,17 @@ augroup vimtex_events
au User VimtexEventQuit call vimtex#compiler#clean(1)
au User VimtexEventQuit call VimtexAdditionalCleanup(template_list)
" auto-compile
" Auto-compile
au User VimtexEventInitPost call vimtex#compiler#compile()
augroup END
" open nerd-tree at the start of each file opening
" Open nerd-tree at the start of each file opening.
autocmd vimenter * NERDTree
" set list and other listing characters (:h listchars)
" Set list and other listing characters (:h listchars).
set list listchars=tab:→\ ,trail
" show leading spaces
" Show leading spaces.
" SOURCE: https://www.reddit.com/r/vim/comments/5fxsfy/show_leading_spaces/
hi Conceal guibg=NONE ctermbg=NONE ctermfg=DarkGrey
autocmd BufWinEnter * setl conceallevel=1
@ -115,12 +126,12 @@ autocmd BufWinEnter * syn match LeadingSpace /\(^ *\)\@<= / containedin=ALL conc
autocmd BufReadPre * setl conceallevel=1
autocmd BufReadPre * syn match LeadingSpace /\(^ *\)\@<= / containedin=ALL conceal cchar=·
" spell checker (for your local language, anyway)
" Enabling spell checker (for your local language, anyway).
setlocal spell
set spelllang=en_gb
inoremap <C-l> <c-g>u<Esc>[s1z=`]a<c-g>u
" changing style of words
" Changing style of words.
hi clear SpellBad
hi SpellBad cterm=bold,underline ctermfg=red

View File

@ -0,0 +1,72 @@
global !p
# Smartly automate inserting of certain characters.
# Mainly used for smart space insertion.
def smart_space(next_str, auto_str=" ", loose=False):
next_word = ""
if next_str:
if loose == True:
next_word = auto_str
elif next_str[0] in [",", ".", "-", "!", "?", " "]:
next_word = auto_str
return next_word
endglobal
snippet def "Define function with autocompleting docstrings" iw
def ${1:function_name}($2):
"""
${3:To be defined}
`!p
arguments = [ arg.strip() for arg in t[2].split(',') if arg != "self" or len(arg.strip()) > 0 ]
# Format the string with an indent.
snip >> 1
for arg in arguments:
split_arg = arg.split('=')
param = split_arg[0].strip()
if param:
snip += f":param: {param} - @TODO"
`
"""
endsnippet
# Quickly create a class definition.
# This is inspired from the demo GIF from the official GitHub page at https://github.com/sirver/UltiSnips.
snippet class "Class keyword with autocompleting docstrings" iw
class ${1:PICK_A_NAME_CLASS}`!p snip.rv = smart_space(t[2], '(', loose=True)`$2`!p snip.rv = smart_space(t[2], ')', loose=True)`:
""" ${3:Docstring for $1} """
def __init__(${4:self}):
"""
${5:Creates an instance of $1}
`!p
arguments = [ arg.strip() for arg in t[4].split(',') if arg != "self" or len(arg.strip()) > 0 ]
# Format the string with an indent.
snip >> 2
for arg in arguments:
split_arg = arg.split('=')
param = split_arg[0].strip()
if param:
snip += f":param: {param} - @TODO"
`
"""
`!p
# Shift by two indentation level
snip >> 2
snip += "" if not t[2] else f"{t[2]}.__init__(self)"
`
$6
endsnippet
snippet if_main "If __main__" biw
if __name__ == "__main__":
${1:print("Hello world!")}
endsnippet

View File

@ -0,0 +1,26 @@
snippet if "If statement" iw
if [[ ${1:<condition>} ]]; then
${2:<expression>}
fi
endsnippet
snippet while_shift "A dependency-less option parser" iw
while [[ $# -gt 0 ]]; then
do
case $1 in
-h|--help)
echo "$help_section"
exit 0
;;
$2
esac
done
endsnippet
snippet while "While loop" iw
while ${1:<expression>};
do
${2:<expression>}
done
endsnippet

View File

@ -728,8 +728,8 @@ copytmap <ESC> q Q w <C-c>
# It's a keymap group "O" (for opening files with certain programs)
map OC shell code %s
map Oc shell code %d
map OV shell vim %s
map Ov shell vim %d
map OV shell nvim %s
map Ov shell nvim %d
map Oi open_with inkscape %d
map OI open_with inkscape %s
map Of open_with firefox %d

View File

@ -169,7 +169,7 @@ ext djvu, has djview, X, flag f = djview -- "$@"
ext epub, has ebook-viewer, X, flag f = ebook-viewer -- "$@"
ext mobi, has ebook-viewer, X, flag f = ebook-viewer -- "$@"
ext tex = vim "$@"
ext tex = nvim "$@"
#-------------------------------------------
# Image Viewing: