commit a7aa42621cbe11262f9a3685bb4420327b67bfc3
Author: array-in-a-matrix
Date: Sat Jan 8 17:30:13 2022 -0500
added
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..01a7186
--- /dev/null
+++ b/README.md
@@ -0,0 +1,33 @@
+# Dotfiles
+
+I use 2 DE/WM on my Arch Linux system:
+ - KDE/kwin
+ - SwayWM/wlroots
+
+I also use `lightDM` as my display manager.
+
+## SwayWM
+- Terminal: `Alacritty`
+- File Manager: `LF`
+- Bar: `Waybar`
+- Launcher: `Rofi`
+
+## KDE
+- Terminal: `Konsole`
+- File Manager: `Dolphin`
+
+## Other Apps
+ - pywal
+ - unimatrix
+ - pywal
+ - pipes.sh
+ - pfetch
+ - gotop
+ - cava
+ - cmus
+ - neovim
+ - firefox
+ - vscode
+ - zsh
+ - radeontop
+ - lsd
diff --git a/dot_zshenv b/dot_zshenv
new file mode 100644
index 0000000..78dd8eb
--- /dev/null
+++ b/dot_zshenv
@@ -0,0 +1,2 @@
+#!/bin/zsh
+[ -f "$HOME/.config/zsh/env" ] && source "$HOME/.config/zsh/env"
diff --git a/private_dot_config/Kvantum/kvantum.kvconfig b/private_dot_config/Kvantum/kvantum.kvconfig
new file mode 100644
index 0000000..2203a7f
--- /dev/null
+++ b/private_dot_config/Kvantum/kvantum.kvconfig
@@ -0,0 +1,2 @@
+[General]
+theme=Monochrome
diff --git a/private_dot_config/cava/config b/private_dot_config/cava/config
new file mode 100644
index 0000000..d4fa402
--- /dev/null
+++ b/private_dot_config/cava/config
@@ -0,0 +1,166 @@
+## Configuration file for CAVA. Default values are commented out. Use either ';' or '#' for commenting.
+
+
+[general]
+
+# Smoothing mode. Can be 'normal', 'scientific' or 'waves'. DEPRECATED as of 0.6.0
+; mode = normal
+
+# Accepts only non-negative values.
+; framerate = 60
+
+# 'autosens' will attempt to decrease sensitivity if the bars peak. 1 = on, 0 = off
+# new as of 0.6.0 autosens of low values (dynamic range)
+# 'overshoot' allows bars to overshoot (in % of terminal height) without initiating autosens. DEPRECATED as of 0.6.0
+; autosens = 1
+; overshoot = 20
+
+# Manual sensitivity in %. If autosens is enabled, this will only be the initial value.
+# 200 means double height. Accepts only non-negative values.
+; sensitivity = 100
+
+# The number of bars (0-200). 0 sets it to auto (fill up console).
+# Bars' width and space between bars in number of characters.
+; bars = 0
+; bar_width = 2
+; bar_spacing = 1
+
+
+# Lower and higher cutoff frequencies for lowest and highest bars
+# the bandwidth of the visualizer.
+# Note: there is a minimum total bandwidth of 43Mhz x number of bars.
+# Cava will automatically increase the higher cutoff if a too low band is specified.
+; lower_cutoff_freq = 50
+; higher_cutoff_freq = 10000
+
+
+# Seconds with no input before cava goes to sleep mode. Cava will not perform FFT or drawing and
+# only check for input once per second. Cava will wake up once input is detected. 0 = disable.
+; sleep_timer = 0
+
+
+[input]
+
+# Audio capturing method. Possible methods are: 'pulse', 'alsa', 'fifo', 'sndio' or 'shmem'
+# Defaults to 'pulse', 'alsa' or 'fifo', in that order, dependent on what support cava was built with.
+#
+# All input methods uses the same config variable 'source'
+# to define where it should get the audio.
+#
+# For pulseaudio 'source' will be the source. Default: 'auto', which uses the monitor source of the default sink
+# (all pulseaudio sinks(outputs) have 'monitor' sources(inputs) associated with them).
+#
+# For alsa 'source' will be the capture device.
+# For fifo 'source' will be the path to fifo-file.
+# For shmem 'source' will be /squeezelite-AA:BB:CC:DD:EE:FF where 'AA:BB:CC:DD:EE:FF' will be squeezelite's MAC address
+; method = pulse
+; source = auto
+
+; method = alsa
+; source = hw:Loopback,1
+
+; method = fifo
+; source = /tmp/mpd.fifo
+; sample_rate = 44100
+; sample_bits = 16
+
+; method = shmem
+; source = /squeezelite-AA:BB:CC:DD:EE:FF
+
+; method = portaudio
+; source = auto
+
+
+[output]
+
+# Output method. Can be 'ncurses', 'noncurses' or 'raw'.
+# 'noncurses' uses a custom framebuffer technique and draws only changes
+# from frame to frame. 'ncurses' is default if supported
+#
+# 'raw' is an 8 or 16 bit (configurable via the 'bit_format' option) data
+# stream of the bar heights that can be used to send to other applications.
+# 'raw' defaults to 200 bars, which can be adjusted in the 'bars' option above.
+; method = ncurses
+
+# Visual channels. Can be 'stereo' or 'mono'.
+# 'stereo' mirrors both channels with low frequencies in center.
+# 'mono' outputs left to right lowest to highest frequencies.
+# 'mono_option' set mono to either take input from 'left', 'right' or 'average'.
+channels = mono
+; mono_option = average
+
+# Raw output target. A fifo will be created if target does not exist.
+; raw_target = /dev/stdout
+
+# Raw data format. Can be 'binary' or 'ascii'.
+; data_format = binary
+
+# Binary bit format, can be '8bit' (0-255) or '16bit' (0-65530).
+; bit_format = 16bit
+
+# Ascii max value. In 'ascii' mode range will run from 0 to value specified here
+; ascii_max_range = 1000
+
+# Ascii delimiters. In ascii format each bar and frame is separated by a delimiters.
+# Use decimal value in ascii table (i.e. 59 = ';' and 10 = '\n' (line feed)).
+; bar_delimiter = 59
+; frame_delimiter = 10
+
+
+
+[color]
+
+# Colors can be one of seven predefined: black, blue, cyan, green, magenta, red, white, yellow.
+# Or defined by hex code '#xxxxxx' (hex code must be within ''). User defined colors requires
+# ncurses output method and a terminal that can change color definitions such as Gnome-terminal or rxvt.
+# if supported, ncurses mode will be force on if user defined colors are used.
+# default is to keep current terminal color
+; background = default
+; foreground = default
+
+# Gradient mode, only hex defined colors (and thereby ncurses mode) are supported,
+# background must also be defined in hex or remain commented out. 1 = on, 0 = off.
+# You can define as many as 8 different colors. They range from bottom to top of screen
+;gradient = 1
+;gradient_count = 2
+;gradient_color_1 = '#fcfcfc'
+;gradient_color_2 = '#e5edfb'
+;gradient_color_3 = '#cedefa'
+;gradient_color_4 = '#b5d0f9'
+;gradient_color_5 = '#9bc2f8'
+;gradient_color_6 = '#7eb4f6'
+;gradient_color_7 = '#5aa6f5'
+;gradient_color_2 = '#1d99f3'
+
+
+
+[smoothing]
+
+# Percentage value for integral smoothing. Takes values from 0 - 100.
+# Higher values means smoother, but less precise. 0 to disable.
+ integral = 50
+
+# Disables or enables the so-called "Monstercat smoothing" with or without "waves". Set to 0 to disable.
+; monstercat = 0
+; waves = 0
+
+# Set gravity percentage for "drop off". Higher values means bars will drop faster.
+# Accepts only non-negative values. 50 means half gravity, 200 means double. Set to 0 to disable "drop off".
+ gravity = 250
+
+
+# In bar height, bars that would have been lower that this will not be drawn.
+; ignore = 0
+
+
+[eq]
+
+# This one is tricky. You can have as much keys as you want.
+# Remember to uncomment more then one key! More keys = more precision.
+# Look at readme.md on github for further explanations and examples.
+; 1 = 1 # bass
+; 2 = 1
+; 3 = 1 # midtone
+; 4 = 1
+; 5 = 1 # treble
+
diff --git a/private_dot_config/gotop/gotop.conf b/private_dot_config/gotop/gotop.conf
new file mode 100644
index 0000000..4675d04
--- /dev/null
+++ b/private_dot_config/gotop/gotop.conf
@@ -0,0 +1,33 @@
+# Scale graphs to this level; 7 is the default, 2 is zoomed out.
+graphhorizontalscale=7
+# If true, start the UI with the help visible
+helpvisible=false
+# The color scheme to use. See `--list colorschemes`
+colorscheme=default
+# How frequently to update the UI, in nanoseconds
+updateinterval=1000000000
+# If true, show the average CPU load
+averagecpu=false
+# If true, show load per CPU
+percpuload=true
+# Temperature units. C for Celcius, F for Fahrenheit
+tempscale=C
+# If true, display a status bar
+statusbar=true
+# The network interface to monitor
+netinterface=all
+# A layout name. See `--list layouts`
+layout=kitchensink
+# The maximum log file size, in bytes
+maxlogsize=5000000
+# If set, export data as Promethius metrics on the interface:port.
+# E.g., `:8080` (colon is required, interface is not)
+#metricsexportport=
+# Display network IO in mpbs if true
+mbps=true
+# A list of enabled temp sensors. See `--list devices`
+#temperatures=
+# Enable NVidia GPU metrics.
+nvidia=false
+# To configure the NVidia refresh rate, set a duration:
+#nvidiarefresh=30s
diff --git a/private_dot_config/i3/config b/private_dot_config/i3/config
new file mode 100644
index 0000000..c212e65
--- /dev/null
+++ b/private_dot_config/i3/config
@@ -0,0 +1,225 @@
+# This file has been auto-generated by i3-config-wizard(1).
+# It will not be overwritten, so edit it as you like.
+#
+# Should you change your keyboard layout some time, delete
+# this file and re-run i3-config-wizard(1).
+#
+
+# i3 config file (v4)
+#
+# Please see https://i3wm.org/docs/userguide.html for a complete reference!
+
+set $mod Mod4
+
+# Font for window titles. Will also be used by the bar unless a different font
+# is used in the bar {} block below.
+font pango:monospace 8
+
+# This font is widely installed, provides lots of unicode glyphs, right-to-left
+# text rendering and scalability on retina/hidpi displays (thanks to pango).
+#font pango:DejaVu Sans Mono 8
+
+# Start XDG autostart .desktop files using dex. See also
+# https://wiki.archlinux.org/index.php/XDG_Autostart
+exec --no-startup-id dex --autostart --environment i3
+
+# The combination of xss-lock, nm-applet and pactl is a popular choice, so
+# they are included here as an example. Modify as you see fit.
+
+# xss-lock grabs a logind suspend inhibit lock and will use i3lock to lock the
+# screen before suspend. Use loginctl lock-session to lock your screen.
+exec --no-startup-id xss-lock --transfer-sleep-lock -- i3lock --nofork
+
+# NetworkManager is the most popular way to manage wireless networks on Linux,
+# and nm-applet is a desktop environment-independent system tray GUI for it.
+exec --no-startup-id nm-applet
+
+# Use pactl to adjust volume in PulseAudio.
+set $refresh_i3status killall -SIGUSR1 i3status
+bindsym XF86AudioRaiseVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ +10% && $refresh_i3status
+bindsym XF86AudioLowerVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ -10% && $refresh_i3status
+bindsym XF86AudioMute exec --no-startup-id pactl set-sink-mute @DEFAULT_SINK@ toggle && $refresh_i3status
+bindsym XF86AudioMicMute exec --no-startup-id pactl set-source-mute @DEFAULT_SOURCE@ toggle && $refresh_i3status
+
+# Use Mouse+$mod to drag floating windows to their wanted position
+floating_modifier $mod
+
+# start a terminal
+bindsym $mod+Return exec alacritty #i3-sensible-terminal
+
+# kill focused window
+bindsym $mod+Shift+q kill
+
+# start rofi
+bindsym $mod+d exec --no-startup-id rofi -show drun -run-shell-command '{terminal} -e zsh -ic "{cmd} && read"'
+
+# start dmenu (a program launcher)
+#bindsym $mod+d exec --no-startup-id dmenu_run
+# A more modern dmenu replacement is rofi:
+# bindcode $mod+40 exec "rofi -modi drun,run -show drun"
+# There also is i3-dmenu-desktop which only displays applications shipping a
+# .desktop file. It is a wrapper around dmenu, so you need that installed.
+# bindcode $mod+40 exec --no-startup-id i3-dmenu-desktop
+
+# change focus
+bindsym $mod+j focus left
+bindsym $mod+k focus down
+bindsym $mod+l focus up
+bindsym $mod+semicolon focus right
+
+# alternatively, you can use the cursor keys:
+bindsym $mod+Left focus left
+bindsym $mod+Down focus down
+bindsym $mod+Up focus up
+bindsym $mod+Right focus right
+
+# move focused window
+bindsym $mod+Shift+j move left
+bindsym $mod+Shift+k move down
+bindsym $mod+Shift+l move up
+bindsym $mod+Shift+semicolon move right
+
+# alternatively, you can use the cursor keys:
+bindsym $mod+Shift+Left move left
+bindsym $mod+Shift+Down move down
+bindsym $mod+Shift+Up move up
+bindsym $mod+Shift+Right move right
+
+# split in horizontal orientation
+bindsym $mod+h split h
+
+# split in vertical orientation
+bindsym $mod+v split v
+
+# enter fullscreen mode for the focused container
+bindsym $mod+f fullscreen toggle
+
+# change container layout (stacked, tabbed, toggle split)
+bindsym $mod+s layout stacking
+bindsym $mod+w layout tabbed
+bindsym $mod+e layout toggle split
+
+# toggle tiling / floating
+bindsym $mod+Shift+space floating toggle
+
+# change focus between tiling / floating windows
+bindsym $mod+space focus mode_toggle
+
+# focus the parent container
+bindsym $mod+a focus parent
+
+# focus the child container
+#bindsym $mod+d focus child
+
+# Define names for default workspaces for which we configure key bindings later on.
+# We use variables to avoid repeating the names in multiple places.
+set $ws1 "1"
+set $ws2 "2"
+set $ws3 "3"
+set $ws4 "4"
+set $ws5 "5"
+set $ws6 "6"
+set $ws7 "7"
+set $ws8 "8"
+set $ws9 "9"
+set $ws10 "10"
+
+# switch to workspace
+bindsym $mod+1 workspace number $ws1
+bindsym $mod+2 workspace number $ws2
+bindsym $mod+3 workspace number $ws3
+bindsym $mod+4 workspace number $ws4
+bindsym $mod+5 workspace number $ws5
+bindsym $mod+6 workspace number $ws6
+bindsym $mod+7 workspace number $ws7
+bindsym $mod+8 workspace number $ws8
+bindsym $mod+9 workspace number $ws9
+bindsym $mod+0 workspace number $ws10
+
+# move focused container to workspace
+bindsym $mod+Shift+1 move container to workspace number $ws1
+bindsym $mod+Shift+2 move container to workspace number $ws2
+bindsym $mod+Shift+3 move container to workspace number $ws3
+bindsym $mod+Shift+4 move container to workspace number $ws4
+bindsym $mod+Shift+5 move container to workspace number $ws5
+bindsym $mod+Shift+6 move container to workspace number $ws6
+bindsym $mod+Shift+7 move container to workspace number $ws7
+bindsym $mod+Shift+8 move container to workspace number $ws8
+bindsym $mod+Shift+9 move container to workspace number $ws9
+bindsym $mod+Shift+0 move container to workspace number $ws10
+
+# reload the configuration file
+bindsym $mod+Shift+c reload
+# restart i3 inplace (preserves your layout/session, can be used to upgrade i3)
+bindsym $mod+Shift+r restart
+# exit i3 (logs you out of your X session)
+bindsym $mod+Shift+e exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -B 'Yes, exit i3' 'i3-msg exit'"
+
+# resize window (you can also use the mouse for that)
+mode "resize" {
+ # These bindings trigger as soon as you enter the resize mode
+
+ # Pressing left will shrink the window’s width.
+ # Pressing right will grow the window’s width.
+ # Pressing up will shrink the window’s height.
+ # Pressing down will grow the window’s height.
+ bindsym j resize shrink width 10 px or 10 ppt
+ bindsym k resize grow height 10 px or 10 ppt
+ bindsym l resize shrink height 10 px or 10 ppt
+ bindsym semicolon resize grow width 10 px or 10 ppt
+
+ # same bindings, but for the arrow keys
+ bindsym Left resize shrink width 10 px or 10 ppt
+ bindsym Down resize grow height 10 px or 10 ppt
+ bindsym Up resize shrink height 10 px or 10 ppt
+ bindsym Right resize grow width 10 px or 10 ppt
+
+ # back to normal: Enter or Escape or $mod+r
+ bindsym Return mode "default"
+ bindsym Escape mode "default"
+ bindsym $mod+r mode "default"
+}
+
+bindsym $mod+r mode "resize"
+
+#PYWAL ENABLED THEME
+set_from_resource $fg i3wm.color7 #f0f0f0
+set_from_resource $bg i3wm.color2 #f0f0f0
+# class border backgr. text indicator child_border
+client.focused $bg $bg $fg $bg $bg
+client.focused_inactive $bg $bg $fg $bg $bg
+client.unfocused $bg $bg $fg $bg $bg
+client.urgent $bg $bg $fg $bg $bg
+client.placeholder $bg $bg $fg $bg $bg
+client.background $bg
+
+client.focused $bg $bg #000000
+
+
+# Start i3bar to display a workspace bar (plus the system information i3status
+# finds out, if available)
+#bar {
+ #colors {
+ #focused_workspace $bg $bg #000000
+ #active_workspace $fg $fg #000000
+ #inactive_workspace $fg $fg #000000
+ #}
+ #mode hide
+ #hidden_state hide
+ #modifier none
+ #status_command i3status
+#}
+
+# Autostart
+exec "sh ~/.config/i3/autostart.sh"
+
+# set size of floating windows
+for_window [floating] resize set 700 320
+
+# You can also use any non-zero value if you'd like to have a border
+for_window [class=".*"] border pixel 4
+
+bindsym XF86MonBrightnessUp exec brightnessctl -q set +10
+
+bindsym XF86MonBrightnessDown exec brightnessctl -q set 10-
+
diff --git a/private_dot_config/i3/executable_autostart.sh b/private_dot_config/i3/executable_autostart.sh
new file mode 100644
index 0000000..60c13f1
--- /dev/null
+++ b/private_dot_config/i3/executable_autostart.sh
@@ -0,0 +1,15 @@
+# pywal colors
+
+image=$(find -L /home/linux/Pictures/Wallpapers/ -type f | shuf -n1)
+wal -i $image
+cat ~/.cache/wal/sequences
+source ~/.cache/wal/colors-tty.sh
+pywalfox update
+feh --bg-fill "$image"
+
+# polybar
+bash ~/.config/polybar/shapes/scripts/pywal.sh "$image"
+bash ~/.config/polybar/launch.sh --shapes &
+
+# the gaps in i3-gaps
+i3-msg gaps inner all set 20
diff --git a/private_dot_config/lf/executable_cleaner b/private_dot_config/lf/executable_cleaner
new file mode 100644
index 0000000..a184d84
--- /dev/null
+++ b/private_dot_config/lf/executable_cleaner
@@ -0,0 +1,4 @@
+#!/bin/sh
+if [ -n "$FIFO_UEBERZUG" ]; then
+ printf '{"action": "remove", "identifier": "PREVIEW"}\n' > "$FIFO_UEBERZUG"
+fi
diff --git a/private_dot_config/lf/executable_preview b/private_dot_config/lf/executable_preview
new file mode 100644
index 0000000..cddcb60
--- /dev/null
+++ b/private_dot_config/lf/executable_preview
@@ -0,0 +1,71 @@
+#!/bin/sh
+
+image() {
+ if [ -n "$DISPLAY" ] && [ -z "$WAYLAND_DISPLAY" ]; then
+ printf '{"action": "add", "identifier": "PREVIEW", "x": "%s", "y": "%s", "width": "%s", "height": "%s", "scaler": "contain", "path": "%s"}\n' "$4" "$5" "$(($2-1))" "$(($3-1))" "$1" > "$FIFO_UEBERZUG"
+ exit 1
+ else
+ chafa "$1" -s "$4x"
+ fi
+}
+
+batorcat() {
+ file="$1"
+ shift
+ if command -v bat > /dev/null 2>&1
+ then
+ bat --color=always --style=plain --pager=never "$file" "$@"
+ else
+ cat "$file"
+ fi
+}
+
+CACHE="$HOME/.cache/lf/thumbnail.$(stat --printf '%n\0%i\0%F\0%s\0%W\0%Y' -- "$(readlink -f "$1")" | sha256sum | awk '{print $1}'))"
+
+case "$(printf "%s\n" "$(readlink -f "$1")" | awk '{print tolower($0)}')" in
+ *.tgz|*.tar.gz) tar tzf "$1" ;;
+ *.tar.bz2|*.tbz2) tar tjf "$1" ;;
+ *.tar.txz|*.txz) xz --list "$1" ;;
+ *.tar) tar tf "$1" ;;
+ *.zip|*.jar|*.war|*.ear|*.oxt) unzip -l "$1" ;;
+ *.rar) unrar l "$1" ;;
+ *.7z) 7z l "$1" ;;
+ *.[1-8]) man "$1" | col -b ;;
+ *.o) nm "$1";;
+ *.torrent) transmission-show "$1" ;;
+ *.iso) iso-info --no-header -l "$1" ;;
+ *.odt|*.ods|*.odp|*.sxw) odt2txt "$1" ;;
+ *.doc) catdoc "$1" ;;
+ *.docx) docx2txt "$1" - ;;
+ *.xls|*.xlsx)
+ ssconvert --export-type=Gnumeric_stf:stf_csv "$1" "fd://1" | batorcat --language=csv
+ ;;
+ *.wav|*.mp3|*.flac|*.m4a|*.wma|*.ape|*.ac3|*.og[agx]|*.spx|*.opus|*.as[fx]|*.mka)
+ exiftool "$1"
+ ;;
+ *.pdf)
+ [ ! -f "${CACHE}.jpg" ] && \
+ pdftoppm -jpeg -f 1 -singlefile "$1" "$CACHE"
+ image "${CACHE}.jpg" "$2" "$3" "$4" "$5"
+ ;;
+ *.epub)
+ [ ! -f "$CACHE" ] && \
+ epub-thumbnailer "$1" "$CACHE" 1024
+ image "$CACHE" "$2" "$3" "$4" "$5"
+ ;;
+ *.avi|*.mp4|*.wmv|*.dat|*.3gp|*.ogv|*.mkv|*.mpg|*.mpeg|*.vob|*.fl[icv]|*.m2v|*.mov|*.webm|*.ts|*.mts|*.m4v|*.r[am]|*.qt|*.divx)
+ [ ! -f "${CACHE}.jpg" ] && \
+ ffmpegthumbnailer -i "$1" -o "${CACHE}.jpg" -s 0 -q 5
+ image "${CACHE}.jpg" "$2" "$3" "$4" "$5"
+ ;;
+ *.bmp|*.jpg|*.jpeg|*.png|*.xpm|*.webp|*.gif)
+ image "$1" "$2" "$3" "$4" "$5"
+ ;;
+ *.ino)
+ batorcat --language=cpp "$1"
+ ;;
+ *)
+ batorcat "$1"
+ ;;
+esac
+exit 0
diff --git a/private_dot_config/lf/lfrc b/private_dot_config/lf/lfrc
new file mode 100644
index 0000000..5a2c0da
--- /dev/null
+++ b/private_dot_config/lf/lfrc
@@ -0,0 +1,17 @@
+set previewer ~/.config/lf/preview
+set cleaner ~/.config/lf/cleaner
+set drawbox true
+set icons true
+
+cmd git_branch ${{
+ git branch | fzf | xargs git checkout
+ pwd_shell=$(pwd)
+ lf -remote "send $id updir"
+ lf -remote "send $id cd \"$pwd_shell\""
+}}
+map gb :git_branch
+map gp ${{clear; git pull --rebase || true; echo "press ENTER"; read ENTER}}
+map gs ${{clear; git status; echo "press ENTER"; read ENTER}}
+map gl ${{clear; git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit}}
+
+map D :delete
diff --git a/private_dot_config/nvim/init.vim b/private_dot_config/nvim/init.vim
new file mode 100644
index 0000000..7e7d2ff
--- /dev/null
+++ b/private_dot_config/nvim/init.vim
@@ -0,0 +1,52 @@
+set showmatch " show matching
+set mouse=v " middle-click paste with
+set hlsearch " highlight search
+set incsearch " incremental search
+set tabstop=4 " number of columns occupied by a tab
+set softtabstop=4 " see multiple spaces as tabstops so does the right thing
+set expandtab " converts tabs to white space
+set shiftwidth=4 " width for autoindents
+set autoindent " indent a new line the same amount as the line just typed
+set number " add line numbers
+set wildmode=longest,list " get bash-like tab completions
+syntax on " syntax highlighting
+set mouse=a " enable mouse click
+set clipboard=unnamedplus " using system clipboard
+set ttyfast " Speed up scrolling in Vim
+set encoding=utf-8
+set ruler
+set wrap
+set hlsearch
+set smartindent
+set showtabline=2
+set noshowmode
+
+call plug#begin()
+ Plug 'neoclide/coc.nvim', {'branch': 'release'}
+ Plug 'vim-airline/vim-airline'
+ Plug 'vim-airline/vim-airline-themes'
+ Plug 'dylanaraps/wal.vim'
+call plug#end()
+
+" vim-airline costomization
+if !exists('g:airline_symbols')
+ let g:airline_symbols = {}
+endif
+
+colorscheme wal
+
+let g:airline_theme='custom'
+let g:airline#extensions#tabline#enabled = 1
+let g:airline#extensions#whitespace#enabled = 0
+let t_Co=256
+let g:airline_powerline_fonts = 1
+let g:airline_left_sep = ''
+let g:airline_left_alt_sep = ''
+let g:airline_right_sep = ''
+let g:airline_right_alt_sep = ''
+let g:airline_symbols.branch = ''
+let g:airline_symbols.colnr = ' :'
+let g:airline_symbols.readonly = ''
+let g:airline_symbols.linenr = ' :'
+let g:airline_symbols.maxlinenr = '☰ '
+let g:airline_symbols.dirty='⚡'
diff --git a/private_dot_config/nvim/plugged/coc.nvim/LICENSE.md b/private_dot_config/nvim/plugged/coc.nvim/LICENSE.md
new file mode 100644
index 0000000..bee2bf1
--- /dev/null
+++ b/private_dot_config/nvim/plugged/coc.nvim/LICENSE.md
@@ -0,0 +1,7 @@
+Copyright 2018-2018 by Qiming Zhao aaa
+
+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.
diff --git a/private_dot_config/nvim/plugged/coc.nvim/Readme.md b/private_dot_config/nvim/plugged/coc.nvim/Readme.md
new file mode 100644
index 0000000..aa5ed98
--- /dev/null
+++ b/private_dot_config/nvim/plugged/coc.nvim/Readme.md
@@ -0,0 +1,334 @@
+
+
+
+
+
Make your Vim/Neovim as smart as VSCode.
+
+
+
+
+
+
+
+
+
+---
+
+
+
+_True snippet and additional text editing support_
+
+## Why?
+
+- 🚀 **Fast**: [instant increment completion](https://github.com/neoclide/coc.nvim/wiki/Completion-with-sources), increment buffer sync using buffer update events.
+- 💎 **Reliable**: typed language, tested with CI.
+- 🌟 **Featured**: [full LSP support](https://github.com/neoclide/coc.nvim/wiki/Language-servers#supported-features)
+- ❤️ **Flexible**: [configured like VSCode](https://github.com/neoclide/coc.nvim/wiki/Using-the-configuration-file), [extensions work like in VSCode](https://github.com/neoclide/coc.nvim/wiki/Using-coc-extensions)
+
+## Quick Start
+
+Install [nodejs](https://nodejs.org/en/download/) >= 12.12:
+
+```sh
+curl -sL install-node.now.sh/lts | bash
+```
+
+For [vim-plug](https://github.com/junegunn/vim-plug) users:
+
+```vim
+" Use release branch (recommend)
+Plug 'neoclide/coc.nvim', {'branch': 'release'}
+
+" Or build from source code by using yarn: https://yarnpkg.com
+Plug 'neoclide/coc.nvim', {'branch': 'master', 'do': 'yarn install --frozen-lockfile'}
+```
+
+in your `.vimrc` or `init.vim`, then restart Vim and run `:PlugInstall`.
+
+Checkout [Install
+coc.nvim](https://github.com/neoclide/coc.nvim/wiki/Install-coc.nvim) for
+more info.
+
+You **have to** install coc extension or configure language servers for
+LSP support.
+
+Install extensions like:
+
+ :CocInstall coc-json coc-tsserver
+
+Or configure language server in `coc-settings.json` opened by
+`:CocConfig`, like:
+
+```json
+{
+ "languageserver": {
+ "go": {
+ "command": "gopls",
+ "rootPatterns": ["go.mod"],
+ "trace.server": "verbose",
+ "filetypes": ["go"]
+ }
+ }
+}
+```
+
+Checkout wiki for more details:
+
+- [Completion with sources](https://github.com/neoclide/coc.nvim/wiki/Completion-with-sources)
+- [Using the configuration file](https://github.com/neoclide/coc.nvim/wiki/Using-the-configuration-file)
+- [Using coc extensions](https://github.com/neoclide/coc.nvim/wiki/Using-coc-extensions)
+- [Configure language servers](https://github.com/neoclide/coc.nvim/wiki/Language-servers)
+- [F.A.Q](https://github.com/neoclide/coc.nvim/wiki/F.A.Q)
+
+Checkout `:h coc-nvim` for vim interface.
+
+## Example vim configuration
+
+Configuration is required to make coc.nvim easier to work with, since it
+doesn't change your key-mappings or Vim options. This is done as much as
+possible to avoid conflict with your other plugins.
+
+**❗️Important**: Some Vim plugins could change key mappings. Please use
+command like`:verbose imap ` to make sure that your keymap has taken effect.
+
+```vim
+" Set internal encoding of vim, not needed on neovim, since coc.nvim using some
+" unicode characters in the file autoload/float.vim
+set encoding=utf-8
+
+" TextEdit might fail if hidden is not set.
+set hidden
+
+" Some servers have issues with backup files, see #649.
+set nobackup
+set nowritebackup
+
+" Give more space for displaying messages.
+set cmdheight=2
+
+" Having longer updatetime (default is 4000 ms = 4 s) leads to noticeable
+" delays and poor user experience.
+set updatetime=300
+
+" Don't pass messages to |ins-completion-menu|.
+set shortmess+=c
+
+" Always show the signcolumn, otherwise it would shift the text each time
+" diagnostics appear/become resolved.
+if has("nvim-0.5.0") || has("patch-8.1.1564")
+ " Recently vim can merge signcolumn and number column into one
+ set signcolumn=number
+else
+ set signcolumn=yes
+endif
+
+" Use tab for trigger completion with characters ahead and navigate.
+" NOTE: Use command ':verbose imap ' to make sure tab is not mapped by
+" other plugin before putting this into your config.
+inoremap
+ \ pumvisible() ? "\" :
+ \ check_back_space() ? "\" :
+ \ coc#refresh()
+inoremap pumvisible() ? "\" : "\"
+
+function! s:check_back_space() abort
+ let col = col('.') - 1
+ return !col || getline('.')[col - 1] =~# '\s'
+endfunction
+
+" Use to trigger completion.
+if has('nvim')
+ inoremap coc#refresh()
+else
+ inoremap coc#refresh()
+endif
+
+" Make auto-select the first completion item and notify coc.nvim to
+" format on enter, could be remapped by other vim plugin
+inoremap pumvisible() ? coc#_select_confirm()
+ \: "\u\\=coc#on_enter()\"
+
+" Use `[g` and `]g` to navigate diagnostics
+" Use `:CocDiagnostics` to get all diagnostics of current buffer in location list.
+nmap [g (coc-diagnostic-prev)
+nmap ]g (coc-diagnostic-next)
+
+" GoTo code navigation.
+nmap gd (coc-definition)
+nmap gy (coc-type-definition)
+nmap gi (coc-implementation)
+nmap gr (coc-references)
+
+" Use K to show documentation in preview window.
+nnoremap K :call show_documentation()
+
+function! s:show_documentation()
+ if (index(['vim','help'], &filetype) >= 0)
+ execute 'h '.expand('')
+ elseif (coc#rpc#ready())
+ call CocActionAsync('doHover')
+ else
+ execute '!' . &keywordprg . " " . expand('')
+ endif
+endfunction
+
+" Highlight the symbol and its references when holding the cursor.
+autocmd CursorHold * silent call CocActionAsync('highlight')
+
+" Symbol renaming.
+nmap rn (coc-rename)
+
+" Formatting selected code.
+xmap f (coc-format-selected)
+nmap f (coc-format-selected)
+
+augroup mygroup
+ autocmd!
+ " Setup formatexpr specified filetype(s).
+ autocmd FileType typescript,json setl formatexpr=CocAction('formatSelected')
+ " Update signature help on jump placeholder.
+ autocmd User CocJumpPlaceholder call CocActionAsync('showSignatureHelp')
+augroup end
+
+" Applying codeAction to the selected region.
+" Example: `aap` for current paragraph
+xmap a (coc-codeaction-selected)
+nmap a (coc-codeaction-selected)
+
+" Remap keys for applying codeAction to the current buffer.
+nmap ac (coc-codeaction)
+" Apply AutoFix to problem on the current line.
+nmap qf (coc-fix-current)
+
+" Map function and class text objects
+" NOTE: Requires 'textDocument.documentSymbol' support from the language server.
+xmap if (coc-funcobj-i)
+omap if (coc-funcobj-i)
+xmap af (coc-funcobj-a)
+omap af (coc-funcobj-a)
+xmap ic (coc-classobj-i)
+omap ic (coc-classobj-i)
+xmap ac (coc-classobj-a)
+omap ac (coc-classobj-a)
+
+" Remap and for scroll float windows/popups.
+if has('nvim-0.4.0') || has('patch-8.2.0750')
+ nnoremap coc#float#has_scroll() ? coc#float#scroll(1) : "\"
+ nnoremap coc#float#has_scroll() ? coc#float#scroll(0) : "\"
+ inoremap coc#float#has_scroll() ? "\=coc#float#scroll(1)\" : "\"
+ inoremap coc#float#has_scroll() ? "\=coc#float#scroll(0)\" : "\"
+ vnoremap coc#float#has_scroll() ? coc#float#scroll(1) : "\"
+ vnoremap coc#float#has_scroll() ? coc#float#scroll(0) : "\"
+endif
+
+" Use CTRL-S for selections ranges.
+" Requires 'textDocument/selectionRange' support of language server.
+nmap (coc-range-select)
+xmap (coc-range-select)
+
+" Add `:Format` command to format current buffer.
+command! -nargs=0 Format :call CocAction('format')
+
+" Add `:Fold` command to fold current buffer.
+command! -nargs=? Fold :call CocAction('fold', )
+
+" Add `:OR` command for organize imports of the current buffer.
+command! -nargs=0 OR :call CocAction('runCommand', 'editor.action.organizeImport')
+
+" Add (Neo)Vim's native statusline support.
+" NOTE: Please see `:h coc-status` for integrations with external plugins that
+" provide custom statusline: lightline.vim, vim-airline.
+set statusline^=%{coc#status()}%{get(b:,'coc_current_function','')}
+
+" Mappings for CoCList
+" Show all diagnostics.
+nnoremap a :CocList diagnostics
+" Manage extensions.
+nnoremap e :CocList extensions
+" Show commands.
+nnoremap c :CocList commands
+" Find symbol of current document.
+nnoremap o :CocList outline
+" Search workspace symbols.
+nnoremap s :CocList -I symbols
+" Do default action for next item.
+nnoremap j :CocNext
+" Do default action for previous item.
+nnoremap k :CocPrev
+" Resume latest coc list.
+nnoremap p :CocListResume
+```
+
+## Articles
+
+- [coc.nvim 插件体系介绍](https://zhuanlan.zhihu.com/p/65524706)
+- [CocList 入坑指南](https://zhuanlan.zhihu.com/p/71846145)
+- [Create coc.nvim extension to improve Vim experience](https://medium.com/@chemzqm/create-coc-nvim-extension-to-improve-vim-experience-4461df269173)
+- [How to write a coc.nvim extension (and why)](https://samroeca.com/coc-plugin.html)
+
+## Trouble shooting
+
+Try these steps when you have problem with coc.nvim.
+
+- Make sure your Vim version >= 8.0 by command `:version`.
+- If service failed to start, use command `:CocInfo` or `:checkhealth` on Neovim.
+- Checkout the log of coc.nvim by command `:CocOpenLog`.
+- When you have issues with the language server, it's recommended to [checkout
+ the output](https://github.com/neoclide/coc.nvim/wiki/Debug-language-server#using-output-channel).
+
+## Feedback
+
+- If you think Coc is useful, consider giving it a star.
+- If you have a question, [ask on gitter](https://gitter.im/neoclide/coc.nvim)
+- 中文用户请到 [中文 gitter](https://gitter.im/neoclide/coc-cn) 讨论
+- If something is not working, [create an
+ issue](https://github.com/neoclide/coc.nvim/issues/new).
+
+## Backers
+
+[Become a backer](https://opencollective.com/cocnvim#backer) and get your image on our README on Github with a link to your site.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+## Support the project
+
+Buy cloud service from [www.vultr.com](https://www.vultr.com/?ref=8890170-6G)
+
+## License
+
+MIT
diff --git a/private_dot_config/nvim/plugged/coc.nvim/autoload/coc.vim b/private_dot_config/nvim/plugged/coc.nvim/autoload/coc.vim
new file mode 100644
index 0000000..e7bf2df
--- /dev/null
+++ b/private_dot_config/nvim/plugged/coc.nvim/autoload/coc.vim
@@ -0,0 +1,196 @@
+scriptencoding utf-8
+let g:coc#_context = {'start': 0, 'preselect': -1,'candidates': []}
+let g:coc_user_config = get(g:, 'coc_user_config', {})
+let g:coc_global_extensions = get(g:, 'coc_global_extensions', [])
+let g:coc_selected_text = ''
+let g:coc_vim_commands = []
+let s:watched_keys = []
+let s:is_vim = !has('nvim')
+let s:error_sign = get(g:, 'coc_status_error_sign', has('mac') ? '❌ ' : 'E')
+let s:warning_sign = get(g:, 'coc_status_warning_sign', has('mac') ? '⚠️ ' : 'W')
+let s:select_api = exists('*nvim_select_popupmenu_item')
+let s:callbacks = {}
+
+function! coc#expandable() abort
+ return coc#rpc#request('snippetCheck', [1, 0])
+endfunction
+
+function! coc#jumpable() abort
+ return coc#rpc#request('snippetCheck', [0, 1])
+endfunction
+
+function! coc#expandableOrJumpable() abort
+ return coc#rpc#request('snippetCheck', [1, 1])
+endfunction
+
+" add vim command to CocCommand list
+function! coc#add_command(id, cmd, ...)
+ let config = {'id':a:id, 'cmd':a:cmd, 'title': get(a:,1,'')}
+ call add(g:coc_vim_commands, config)
+ if !coc#rpc#ready() | return | endif
+ call coc#rpc#notify('addCommand', [config])
+endfunction
+
+function! coc#refresh() abort
+ return "\=coc#start()\"
+endfunction
+
+function! coc#on_enter()
+ call coc#rpc#notify('CocAutocmd', ['Enter', bufnr('%')])
+ return ''
+endfunction
+
+function! coc#_insert_key(method, key, ...) abort
+ if get(a:, 1, 1)
+ call coc#_cancel()
+ endif
+ return "\=coc#rpc#".a:method."('doKeymap', ['".a:key."'])\"
+endfunction
+
+function! coc#_complete() abort
+ let items = get(g:coc#_context, 'candidates', [])
+ let preselect = get(g:coc#_context, 'preselect', -1)
+ let startcol = g:coc#_context.start + 1
+ if s:select_api && len(items) && preselect != -1
+ noa call complete(startcol, items)
+ call nvim_select_popupmenu_item(preselect, v:false, v:false, {})
+ " use specific key to preselect item at once
+ call feedkeys("\\" , 'i')
+ else
+ call complete(startcol, items)
+ endif
+ return ''
+endfunction
+
+function! coc#_do_complete(start, items, preselect)
+ let g:coc#_context = {
+ \ 'start': a:start,
+ \ 'candidates': a:items,
+ \ 'preselect': a:preselect
+ \}
+ if mode() =~# 'i' && &paste != 1
+ call feedkeys("\CocRefresh", 'i')
+ endif
+endfunction
+
+function! coc#_select_confirm() abort
+ if !exists('*complete_info')
+ throw 'coc#_select_confirm requires complete_info function to work'
+ endif
+ let selected = complete_info()['selected']
+ if selected != -1
+ return "\"
+ elseif pumvisible()
+ return "\\"
+ endif
+ return ''
+endfunction
+
+function! coc#_selected()
+ if !pumvisible() | return 0 | endif
+ return coc#rpc#request('hasSelected', [])
+endfunction
+
+function! coc#_hide() abort
+ if !pumvisible() | return | endif
+ call feedkeys("\", 'in')
+endfunction
+
+function! coc#_cancel()
+ " hack for close pum
+ if pumvisible()
+ let g:coc#_context = {'start': 0, 'preselect': -1,'candidates': []}
+ call feedkeys("\CocRefresh", 'i')
+ call coc#rpc#notify('stopCompletion', [])
+ endif
+endfunction
+
+function! coc#_select() abort
+ if !pumvisible() | return | endif
+ call feedkeys("\", 'in')
+endfunction
+
+function! coc#start(...)
+ let opt = coc#util#get_complete_option()
+ call CocActionAsync('startCompletion', extend(opt, get(a:, 1, {})))
+ return ''
+endfunction
+
+" used for statusline
+function! coc#status()
+ let info = get(b:, 'coc_diagnostic_info', {})
+ let msgs = []
+ if !empty(info) && get(info, 'error', 0)
+ call add(msgs, s:error_sign . info['error'])
+ endif
+ if !empty(info) && get(info, 'warning', 0)
+ call add(msgs, s:warning_sign . info['warning'])
+ endif
+ return s:trim(join(msgs, ' ') . ' ' . get(g:, 'coc_status', ''))
+endfunction
+
+function! s:trim(str)
+ if exists('*trim')
+ return trim(a:str)
+ endif
+ return substitute(a:str, '\s\+$', '', '')
+endfunction
+
+function! coc#config(section, value)
+ let g:coc_user_config[a:section] = a:value
+ call coc#rpc#notify('updateConfig', [a:section, a:value])
+endfunction
+
+function! coc#add_extension(...)
+ if a:0 == 0 | return | endif
+ call extend(g:coc_global_extensions, a:000)
+endfunction
+
+function! coc#_watch(key)
+ if s:is_vim | return | endif
+ if index(s:watched_keys, a:key) == -1
+ call add(s:watched_keys, a:key)
+ call dictwatcheradd(g:, a:key, function('s:GlobalChange'))
+ endif
+endfunction
+
+function! coc#_unwatch(key)
+ if s:is_vim | return | endif
+ let idx = index(s:watched_keys, a:key)
+ if idx != -1
+ call remove(s:watched_keys, idx)
+ call dictwatcherdel(g:, a:key, function('s:GlobalChange'))
+ endif
+endfunction
+
+function! s:GlobalChange(dict, key, val)
+ call coc#rpc#notify('GlobalChange', [a:key, get(a:val, 'old', v:null), get(a:val, 'new', v:null)])
+endfunction
+
+function! coc#_map()
+ if !s:select_api | return | endif
+ for i in range(1, 9)
+ exe 'inoremap '.i.' call nvim_select_popupmenu_item('.(i - 1).', v:true, v:true, {})'
+ endfor
+endfunction
+
+function! coc#_unmap()
+ if !s:select_api | return | endif
+ for i in range(1, 9)
+ exe 'silent! iunmap '.i
+ endfor
+endfunction
+
+function! coc#on_notify(id, method, Cb)
+ let key = a:id. '-'.a:method
+ let s:callbacks[key] = a:Cb
+ call coc#rpc#notify('registNotification', [a:id, a:method])
+endfunction
+
+function! coc#do_notify(id, method, result)
+ let key = a:id. '-'.a:method
+ let Fn = s:callbacks[key]
+ if !empty(Fn)
+ call Fn(a:result)
+ endif
+endfunction
diff --git a/private_dot_config/nvim/plugged/coc.nvim/autoload/coc/api.vim b/private_dot_config/nvim/plugged/coc.nvim/autoload/coc/api.vim
new file mode 100644
index 0000000..3dc4ae3
--- /dev/null
+++ b/private_dot_config/nvim/plugged/coc.nvim/autoload/coc/api.vim
@@ -0,0 +1,634 @@
+" ============================================================================
+" Description: Client api used by vim8
+" Author: Qiming Zhao
+" Licence: MIT licence
+" Last Modified: Aug 10, 2021
+" ============================================================================
+if has('nvim') | finish | endif
+scriptencoding utf-8
+let s:funcs = {}
+let s:prop_offset = get(g:, 'coc_text_prop_offset', 1000)
+let s:namespace_id = 1
+let s:namespace_cache = {}
+
+" helper {{
+function! s:buf_line_count(bufnr) abort
+ if bufnr('%') == a:bufnr
+ return line('$')
+ endif
+ if exists('*getbufinfo')
+ let info = getbufinfo(a:bufnr)
+ if empty(info)
+ return 0
+ endif
+ return info[0]['linecount']
+ endif
+ if exists('*getbufline')
+ let lines = getbufline(a:bufnr, 1, '$')
+ return len(lines)
+ endif
+ let curr = bufnr('%')
+ execute 'buffer '.a:bufnr
+ let n = line('$')
+ execute 'buffer '.curr
+ return n
+endfunction
+
+function! s:execute(cmd)
+ if a:cmd =~# '^echo'
+ execute a:cmd
+ else
+ silent! execute a:cmd
+ endif
+endfunction
+" }}"
+
+" nvim client methods {{
+function! s:funcs.set_current_dir(dir) abort
+ execute 'cd '.a:dir
+endfunction
+
+function! s:funcs.set_var(name, value) abort
+ execute 'let g:'.a:name.'= a:value'
+endfunction
+
+function! s:funcs.del_var(name) abort
+ execute 'unlet g:'.a:name
+endfunction
+
+function! s:funcs.set_option(name, value) abort
+ execute 'let &'.a:name.' = a:value'
+endfunction
+
+function! s:funcs.set_current_buf(bufnr) abort
+ if !bufexists(a:bufnr) | return | endif
+ execute 'buffer '.a:bufnr
+endfunction
+
+function! s:funcs.set_current_win(win_id) abort
+ let [tabnr, winnr] = win_id2tabwin(a:win_id)
+ if tabnr == 0 | return | endif
+ execute 'normal! '.tabnr.'gt'
+ execute winnr.' wincmd w'
+endfunction
+
+function! s:funcs.set_current_tabpage(tabnr) abort
+ execute 'normal! '.a:tabnr.'gt'
+endfunction
+
+function! s:funcs.list_wins() abort
+ return map(getwininfo(), 'v:val["winid"]')
+endfunction
+
+function s:inspect_type(v) abort
+ let types = ['Number', 'String', 'Funcref', 'List', 'Dictionary', 'Float', 'Boolean', 'Null']
+ return get(types, type(a:v), 'Unknown')
+endfunction
+
+function! s:funcs.call_atomic(calls)
+ let res = []
+ for i in range(len(a:calls))
+ let [key, arglist] = a:calls[i]
+ let name = key[5:]
+ try
+ call add(res, call(s:funcs[name], arglist))
+ catch /.*/
+ return [res, [i, "VimException(".s:inspect_type(v:exception).")", v:exception]]
+ endtry
+ endfor
+ return [res, v:null]
+endfunction
+
+function! s:funcs.set_client_info(...) abort
+endfunction
+
+function! s:funcs.subscribe(...) abort
+endfunction
+
+function! s:funcs.unsubscribe(...) abort
+endfunction
+
+function! s:funcs.call_function(method, args) abort
+ return call(a:method, a:args)
+endfunction
+
+function! s:funcs.call_dict_function(dict, method, args) abort
+ return call(a:method, a:args, a:dict)
+endfunction
+
+function! s:funcs.command(command) abort
+ " command that could cause cursor vanish
+ if a:command =~# '^echo' || a:command =~# '^redraw' || a:command =~# '^sign place'
+ call timer_start(0, {-> s:execute(a:command)})
+ else
+ execute a:command
+ let err = get(g:, 'errmsg', '')
+ " get error from python script run.
+ if !empty(err)
+ unlet g:errmsg
+ throw err
+ endif
+ endif
+endfunction
+
+function! s:funcs.eval(expr) abort
+ return eval(a:expr)
+endfunction
+
+function! s:funcs.get_api_info()
+ let names = coc#api#func_names()
+ return [1, {'functions': map(names, '{"name": "nvim_".v:val}')}]
+endfunction
+
+function! s:funcs.list_bufs()
+ return map(getbufinfo({'bufloaded': 1}), 'v:val["bufnr"]')
+endfunction
+
+function! s:funcs.feedkeys(keys, mode, escape_csi)
+ call feedkeys(a:keys, a:mode)
+endfunction
+
+function! s:funcs.list_runtime_paths()
+ return split(&runtimepath, ',')
+endfunction
+
+function! s:funcs.command_output(cmd)
+ return execute(a:cmd)
+endfunction
+
+function! s:funcs.get_current_line()
+ return getline('.')
+endfunction
+
+function! s:funcs.set_current_line(line)
+ call setline('.', a:line)
+endfunction
+
+function! s:funcs.del_current_line(line)
+ execute 'normal! dd'
+endfunction
+
+function! s:funcs.get_var(var)
+ return get(g:, a:var, v:null)
+endfunction
+
+function! s:funcs.get_vvar(var)
+ return get(v:, a:var, v:null)
+endfunction
+
+function! s:funcs.get_option(name)
+ return eval('&'.a:name)
+endfunction
+
+function! s:funcs.get_current_buf()
+ return bufnr('%')
+endfunction
+
+function! s:funcs.get_current_win()
+ return win_getid()
+endfunction
+
+function! s:funcs.get_current_tabpage()
+ return tabpagenr()
+endfunction
+
+function! s:funcs.list_tabpages()
+ return range(1, tabpagenr('$'))
+endfunction
+
+function! s:funcs.get_mode()
+ return {'blocking': v:false, 'mode': mode()}
+endfunction
+
+function! s:funcs.strwidth(str)
+ return strwidth(a:str)
+endfunction
+
+function! s:funcs.out_write(str)
+ echon a:str
+ call timer_start(0, {-> s:execute('redraw')})
+endfunction
+
+function! s:funcs.err_write(str)
+ "echoerr a:str
+endfunction
+
+function! s:funcs.err_writeln(str)
+ echohl ErrorMsg
+ echom a:str
+ echohl None
+ call timer_start(0, {-> s:execute('redraw')})
+endfunction
+
+function! s:funcs.create_namespace(name) abort
+ if empty(a:name)
+ let id = s:namespace_id
+ let s:namespace_id = s:namespace_id + 1
+ return id
+ endif
+ let id = get(s:namespace_cache, a:name, 0)
+ if !id
+ let id = s:namespace_id
+ let s:namespace_id = s:namespace_id + 1
+ let s:namespace_cache[a:name] = id
+ endif
+ return id
+endfunction
+" }}
+
+" buffer methods {{
+function! s:funcs.buf_set_option(bufnr, name, val)
+ let val = a:val
+ if val is v:true
+ let val = 1
+ elseif val is v:false
+ let val = 0
+ endif
+ return setbufvar(a:bufnr, '&'.a:name, val)
+endfunction
+
+function! s:funcs.buf_get_changedtick(bufnr)
+ return getbufvar(a:bufnr, 'changedtick')
+endfunction
+
+function! s:funcs.buf_is_valid(bufnr)
+ return bufloaded(a:bufnr) ? v:true : v:false
+endfunction
+
+function! s:funcs.buf_get_mark(bufnr, name)
+ let nr = bufnr('%')
+ if a:bufnr != 0 || a:bufnr != nr
+ throw 'buf_get_mark support current buffer only'
+ endif
+ return [line("'" . a:name), col("'" . a:name)]
+endfunction
+
+function! s:funcs.buf_add_highlight(bufnr, srcId, hlGroup, line, colStart, colEnd) abort
+ if !has('textprop') || !has('patch-8.1.1719')
+ return
+ endif
+ let bufnr = a:bufnr == 0 ? bufnr('%') : a:bufnr
+ let type = 'CocHighlight'.a:hlGroup
+ if empty(prop_type_get(type))
+ call prop_type_add(type, {'highlight': a:hlGroup, 'combine': 1})
+ endif
+ let total = strlen(getbufline(bufnr, a:line + 1)[0])
+ let end = a:colEnd
+ if end == -1
+ let end = total
+ else
+ let end = min([end, total])
+ endif
+ if end <= a:colStart
+ return
+ endif
+ let srcId = a:srcId
+ if srcId == 0
+ while v:true
+ let srcId = srcId + 1
+ if empty(prop_find({'id': s:prop_offset + srcId, 'lnum' : 1}))
+ break
+ endif
+ endwhile
+ " generate srcId
+ endif
+ let id = srcId == -1 ? 0 : s:prop_offset + srcId
+ try
+ call prop_add(a:line + 1, a:colStart + 1, {'length': end - a:colStart, 'bufnr': bufnr, 'type': type, 'id': id})
+ catch /^Vim\%((\a\+)\)\=:E967/
+ " ignore 967
+ endtry
+ if a:srcId == 0
+ " return generated srcId
+ return srcId
+ endif
+endfunction
+
+function! s:funcs.buf_clear_namespace(bufnr, srcId, startLine, endLine) abort
+ if !has('textprop') || !has('patch-8.1.1719')
+ return
+ endif
+ let bufnr = a:bufnr == 0 ? bufnr('%') : a:bufnr
+ let start = a:startLine + 1
+ let end = a:endLine == -1 ? len(getbufline(bufnr, 1, '$')) : a:endLine + 1
+ if a:srcId == -1
+ call prop_clear(start, end, {'bufnr' : bufnr})
+ else
+ try
+ call prop_remove({'bufnr': bufnr, 'all': 1, 'id': s:prop_offset + a:srcId}, start, end)
+ catch /^Vim\%((\a\+)\)\=:E968/
+ " ignore 968
+ endtry
+ endif
+endfunction
+
+function! s:funcs.buf_line_count(bufnr) abort
+ return s:buf_line_count(a:bufnr)
+endfunction
+
+function! s:funcs.buf_attach(...)
+ " not supported
+ return 1
+endfunction
+
+function! s:funcs.buf_detach()
+ " not supported
+ return 1
+endfunction
+
+function! s:funcs.buf_get_lines(bufnr, start, end, strict) abort
+ let lines = getbufline(a:bufnr, 1, '$')
+ let start = a:start < 0 ? a:start + 1 : a:start
+ let end = a:end < 0 ? a:end + 1 : a:end
+ if a:strict && end > len(lines)
+ throw 'line number out of range: '. end
+ endif
+ return lines[start : end - 1]
+endfunction
+
+function! s:funcs.buf_set_lines(bufnr, start, end, strict, ...) abort
+ if !bufloaded(a:bufnr)
+ return
+ endif
+ let replacement = get(a:, 1, [])
+ let lineCount = s:buf_line_count(a:bufnr)
+ let startLnum = a:start >= 0 ? a:start + 1 : lineCount + a:start + 1
+ let end = a:end >= 0 ? a:end : lineCount + a:end + 1
+ if end == lineCount + 1
+ let end = lineCount
+ endif
+ let delCount = end - (startLnum - 1)
+ let changeBuffer = 0
+ let curr = bufnr('%')
+ if a:bufnr != curr && !exists('*setbufline')
+ let changeBuffer = 1
+ exe 'buffer '.a:bufnr
+ endif
+ if a:bufnr == curr || changeBuffer
+ " replace
+ let storeView = winsaveview()
+ if delCount == len(replacement)
+ call setline(startLnum, replacement)
+ else
+ if len(replacement)
+ call append(startLnum - 1, replacement)
+ endif
+ if delCount
+ let start = startLnum + len(replacement)
+ let saved_reg = @"
+ silent execute start . ','.(start + delCount - 1).'d'
+ let @" = saved_reg
+ endif
+ endif
+ call winrestview(storeView)
+ if changeBuffer
+ exe 'buffer '.curr
+ endif
+ elseif exists('*setbufline')
+ " replace
+ if delCount == len(replacement)
+ " 8.0.1039
+ call setbufline(a:bufnr, startLnum, replacement)
+ else
+ if len(replacement)
+ " 8.10037
+ call appendbufline(a:bufnr, startLnum - 1, replacement)
+ endif
+ if delCount
+ let start = startLnum + len(replacement)
+ "8.1.0039
+ silent call deletebufline(a:bufnr, start, start + delCount - 1)
+ endif
+ endif
+ endif
+endfunction
+
+function! s:funcs.buf_set_name(bufnr, name) abort
+ let nr = bufnr('%')
+ if a:bufnr != nr
+ throw 'buf_set_name support current buffer only'
+ else
+ execute '0f'
+ execute 'file '.fnameescape(a:name)
+ endif
+endfunction
+
+function! s:funcs.buf_get_var(bufnr, name)
+ return getbufvar(a:bufnr, a:name)
+endfunction
+
+function! s:funcs.buf_set_var(bufnr, name, val)
+ if !bufloaded(a:bufnr) | return | endif
+ call setbufvar(a:bufnr, a:name, a:val)
+endfunction
+
+function! s:funcs.buf_del_var(bufnr, name)
+ call coc#compat#buf_del_var(a:bufnr, a:name)
+endfunction
+
+function! s:funcs.buf_get_option(bufnr, name)
+ return getbufvar(a:bufnr, '&'.a:name)
+endfunction
+
+function! s:funcs.buf_get_name(bufnr)
+ return bufname(a:bufnr)
+endfunction
+" }}
+
+" window methods {{
+function! s:funcs.win_get_buf(winid)
+ return winbufnr(a:winid)
+endfunction
+
+function! s:funcs.win_get_position(win_id) abort
+ let [row, col] = win_screenpos(a:win_id)
+ if row == 0 && col == 0
+ throw 'Invalid window '.a:win_id
+ endif
+ return [row - 1, col - 1]
+endfunction
+
+function! s:funcs.win_get_height(win_id) abort
+ return winheight(a:win_id)
+endfunction
+
+function! s:funcs.win_get_width(win_id) abort
+ return winwidth(a:win_id)
+endfunction
+
+if exists('*win_execute')
+ function! s:win_execute(win_id, cmd, ...) abort
+ let ref = get(a:000, 0, v:null)
+ let cmd = ref is v:null ? a:cmd : 'let ref["out"] = ' . a:cmd
+ call win_execute(a:win_id, cmd)
+ endfunction
+else
+ function! s:win_execute(win_id, cmd, ...) abort
+ let ref = get(a:000, 0, v:null)
+ let cmd = ref is v:null ? a:cmd : 'let ref["out"] = ' . a:cmd
+ let winid = win_getid()
+ if winid == a:win_id
+ execute cmd
+ else
+ let goto_status = win_gotoid(a:win_id)
+ if !goto_status
+ return
+ endif
+ execute cmd
+ call win_gotoid(winid)
+ endif
+ endfunction
+endif
+
+function! s:get_tabnr(winid) abort
+ let ref = {}
+ call s:win_execute(a:winid, 'tabpagenr()', ref)
+ return get(ref, 'out', 0)
+endfunction
+
+function! s:funcs.win_get_cursor(win_id) abort
+ let ref = {}
+ call s:win_execute(a:win_id, "[line('.'), col('.')-1]", ref)
+ return get(ref, 'out', 0)
+endfunction
+
+function! s:funcs.win_get_var(win_id, name) abort
+ let tabnr = s:get_tabnr(a:win_id)
+ if tabnr
+ return gettabwinvar(tabnr, a:win_id, a:name)
+ endif
+ throw 'window '.a:win_id. ' not a valid window'
+endfunction
+
+function! s:funcs.win_set_width(win_id, width) abort
+ call s:win_execute(a:win_id, 'vertical resize '.a:width)
+endfunction
+
+function! s:funcs.win_set_buf(win_id, buf_id) abort
+ call s:win_execute(a:win_id, 'buffer '.a:buf_id)
+endfunction
+
+function! s:funcs.win_get_option(win_id, name) abort
+ let tabnr = s:get_tabnr(a:win_id)
+ if tabnr
+ return gettabwinvar(tabnr, a:win_id, '&'.a:name)
+ endif
+ throw 'window '.a:win_id. ' not a valid window'
+endfunction
+
+function! s:funcs.win_set_height(win_id, height) abort
+ return s:win_execute(a:win_id, 'resize '.a:height)
+endfunction
+
+function! s:funcs.win_set_option(win_id, name, value) abort
+ let val = a:value
+ if val is v:true
+ let val = 1
+ elseif val is v:false
+ let val = 0
+ endif
+ let tabnr = s:get_tabnr(a:win_id)
+ if tabnr
+ call settabwinvar(tabnr, a:win_id, '&'.a:name, val)
+ else
+ throw 'window '.a:win_id. ' not a valid window'
+ endif
+endfunction
+
+function! s:funcs.win_set_var(win_id, name, value) abort
+ let tabnr = s:get_tabnr(a:win_id)
+ if tabnr
+ call settabwinvar(tabnr, a:win_id, a:name, a:value)
+ else
+ throw 'window '.a:win_id. ' not a valid window'
+ endif
+endfunction
+
+function! s:funcs.win_del_var(win_id, name) abort
+ call s:win_execute(a:win_id, 'unlet! w:'.a:name)
+endfunction
+
+function! s:funcs.win_is_valid(win_id) abort
+ let info = getwininfo(a:win_id)
+ return empty(info) ? v:false : v:true
+endfunction
+
+function! s:funcs.win_get_number(win_id) abort
+ let info = getwininfo(a:win_id)
+ if empty(info)
+ throw 'Invalid window id '.a:win_id
+ endif
+ return info[0]['winnr']
+endfunction
+
+function! s:funcs.win_set_cursor(win_id, pos) abort
+ let [line, col] = a:pos
+ call s:win_execute(a:win_id, 'call cursor('.line.','.(col + 1).')')
+endfunction
+
+function! s:funcs.win_close(win_id, ...) abort
+ let force = get(a:, 1, 0)
+ call s:win_execute(a:win_id, 'close'.(force ? '!' : ''))
+endfunction
+
+function! s:funcs.win_get_tabpage(win_id) abort
+ let tabnr = s:get_tabnr(a:win_id)
+ if !tabnr
+ throw 'Invalid window id '.a:win_id
+ endif
+ return tabnr
+endfunction
+" }}
+
+" tabpage methods {{
+function! s:funcs.tabpage_get_number(id)
+ return a:id
+endfunction
+
+function! s:funcs.tabpage_list_wins(tabnr)
+ let info = getwininfo()
+ return map(filter(info, 'v:val["tabnr"] == a:tabnr'), 'v:val["winid"]')
+endfunction
+
+function! s:funcs.tabpage_get_var(tabnr, name)
+ return gettabvar(a:tabnr, a:name, v:null)
+endfunction
+
+function! s:funcs.tabpage_set_var(tabnr, name, value)
+ call settabvar(a:tabnr, a:name, a:value)
+endfunction
+
+function! s:funcs.tabpage_del_var(tabnr, name)
+ call settabvar(a:tabnr, a:name, v:null)
+endfunction
+
+function! s:funcs.tabpage_is_valid(tabnr)
+ let max = tabpagenr('$')
+ return a:tabnr <= max
+endfunction
+
+function! s:funcs.tabpage_get_win(tabnr)
+ let wnr = tabpagewinnr(a:tabnr)
+ return win_getid(wnr, a:tabnr)
+endfunction
+" }}
+
+function! coc#api#func_names() abort
+ return keys(s:funcs)
+endfunction
+
+function! coc#api#call(method, args) abort
+ let err = v:null
+ let res = v:null
+ try
+ let res = call(s:funcs[a:method], a:args)
+ catch /.*/
+ let err = v:exception
+ endtry
+ return [err, res]
+endfunction
+
+function! coc#api#notify(method, args) abort
+ call call(s:funcs[a:method], a:args)
+endfunction
+" vim: set sw=2 ts=2 sts=2 et tw=78 foldmarker={{,}} foldmethod=marker foldlevel=0:
diff --git a/private_dot_config/nvim/plugged/coc.nvim/autoload/coc/client.vim b/private_dot_config/nvim/plugged/coc.nvim/autoload/coc/client.vim
new file mode 100644
index 0000000..6987ebb
--- /dev/null
+++ b/private_dot_config/nvim/plugged/coc.nvim/autoload/coc/client.vim
@@ -0,0 +1,331 @@
+scriptencoding utf-8
+let s:root = expand(':h:h:h')
+let s:is_vim = !has('nvim')
+let s:is_win = has("win32") || has("win64")
+let s:clients = {}
+
+if get(g:, 'node_client_debug', 0)
+ let $NODE_CLIENT_LOG_LEVEL = 'debug'
+ if exists('$NODE_CLIENT_LOG_FILE')
+ let s:logfile = resolve($NODE_CLIENT_LOG_FILE)
+ else
+ let s:logfile = tempname()
+ let $NODE_CLIENT_LOG_FILE = s:logfile
+ endif
+endif
+
+" create a client
+function! coc#client#create(name, command)
+ let client = {}
+ let client['command'] = a:command
+ let client['name'] = a:name
+ let client['running'] = 0
+ let client['async_req_id'] = 1
+ let client['async_callbacks'] = {}
+ " vim only
+ let client['channel'] = v:null
+ " neovim only
+ let client['chan_id'] = 0
+ let client['start'] = function('s:start', [], client)
+ let client['request'] = function('s:request', [], client)
+ let client['notify'] = function('s:notify', [], client)
+ let client['request_async'] = function('s:request_async', [], client)
+ let client['on_async_response'] = function('s:on_async_response', [], client)
+ let s:clients[a:name] = client
+ return client
+endfunction
+
+function! s:start() dict
+ if self.running | return | endif
+ if !isdirectory(getcwd())
+ echohl Error | echon '[coc.nvim] Current cwd is not a valid directory.' | echohl None
+ return
+ endif
+ let timeout = string(get(g:, 'coc_channel_timeout', 30))
+ let disable_warning = string(get(g:, 'coc_disable_startup_warning', 0))
+ let tmpdir = fnamemodify(tempname(), ':p:h')
+ if s:is_vim
+ let options = {
+ \ 'in_mode': 'json',
+ \ 'out_mode': 'json',
+ \ 'err_mode': 'nl',
+ \ 'err_cb': {channel, message -> s:on_stderr(self.name, split(message, "\n"))},
+ \ 'exit_cb': {channel, code -> s:on_exit(self.name, code)},
+ \ 'env': {
+ \ 'NODE_NO_WARNINGS': '1',
+ \ 'VIM_NODE_RPC': '1',
+ \ 'COC_NVIM': '1',
+ \ 'COC_CHANNEL_TIMEOUT': timeout,
+ \ 'TMPDIR': tmpdir,
+ \ }
+ \}
+ if has("patch-8.1.350")
+ let options['noblock'] = 1
+ endif
+ let job = job_start(self.command, options)
+ let status = job_status(job)
+ if status !=# 'run'
+ let self.running = 0
+ echohl Error | echom 'Failed to start '.self.name.' service' | echohl None
+ return
+ endif
+ let self['running'] = 1
+ let self['channel'] = job_getchannel(job)
+ else
+ let original = {}
+ let opts = {
+ \ 'rpc': 1,
+ \ 'on_stderr': {channel, msgs -> s:on_stderr(self.name, msgs)},
+ \ 'on_exit': {channel, code -> s:on_exit(self.name, code)},
+ \ }
+ if has('nvim-0.5.0')
+ " could use env option
+ let opts['env'] = {
+ \ 'NODE_NO_WARNINGS': '1',
+ \ 'COC_CHANNEL_TIMEOUT': timeout,
+ \ 'TMPDIR': tmpdir
+ \ }
+ else
+ let original = {
+ \ 'NODE_NO_WARNINGS': getenv('NODE_NO_WARNINGS'),
+ \ 'TMPDIR': getenv('TMPDIR'),
+ \ }
+ if exists('*setenv')
+ call setenv('NODE_NO_WARNINGS', '1')
+ call setenv('COC_CHANNEL_TIMEOUT', timeout)
+ call setenv('TMPDIR', tmpdir)
+ else
+ let $NODE_NO_WARNINGS = 1
+ let $TMPDIR = tmpdir
+ endif
+ endif
+ let chan_id = jobstart(self.command, opts)
+ if !empty(original)
+ if exists('*setenv')
+ for key in keys(original)
+ call setenv(key, original[key])
+ endfor
+ else
+ let $TMPDIR = original['TMPDIR']
+ endif
+ endif
+ if chan_id <= 0
+ echohl Error | echom 'Failed to start '.self.name.' service' | echohl None
+ return
+ endif
+ let self['chan_id'] = chan_id
+ let self['running'] = 1
+ endif
+endfunction
+
+function! s:on_stderr(name, msgs)
+ if get(g:, 'coc_vim_leaving', 0) | return | endif
+ if get(g:, 'coc_disable_uncaught_error', 0) | return | endif
+ let data = filter(copy(a:msgs), '!empty(v:val)')
+ if empty(data) | return | endif
+ let client = a:name ==# 'coc' ? '[coc.nvim]' : '['.a:name.']'
+ let data[0] = client.': '.data[0]
+ call coc#util#echo_messages('Error', data)
+endfunction
+
+function! s:on_exit(name, code) abort
+ if get(g:, 'coc_vim_leaving', 0) | return | endif
+ let client = get(s:clients, a:name, v:null)
+ if empty(client) | return | endif
+ if client['running'] != 1 | return | endif
+ let client['running'] = 0
+ let client['chan_id'] = 0
+ let client['channel'] = v:null
+ let client['async_req_id'] = 1
+ if a:code != 0 && a:code != 143
+ echohl Error | echom 'client '.a:name. ' abnormal exit with: '.a:code | echohl None
+ endif
+endfunction
+
+function! coc#client#get_client(name) abort
+ return get(s:clients, a:name, v:null)
+endfunction
+
+function! coc#client#get_channel(client)
+ if s:is_vim
+ return a:client['channel']
+ endif
+ return a:client['chan_id']
+endfunction
+
+function! s:request(method, args) dict
+ let channel = coc#client#get_channel(self)
+ if empty(channel) | return '' | endif
+ try
+ if s:is_vim
+ let res = ch_evalexpr(channel, [a:method, a:args], {'timeout': 60 * 1000})
+ if type(res) == 1 && res ==# ''
+ throw 'request '.a:method. ' '.string(a:args).' timeout after 60s'
+ endif
+ let [l:errmsg, res] = res
+ if !empty(l:errmsg)
+ throw l:errmsg
+ else
+ return res
+ endif
+ else
+ return call('rpcrequest', [channel, a:method] + a:args)
+ endif
+ catch /.*/
+ if v:exception =~# 'E475'
+ if get(g:, 'coc_vim_leaving', 0) | return | endif
+ echohl Error | echom '['.self.name.'] server connection lost' | echohl None
+ let name = self.name
+ call s:on_exit(name, 0)
+ execute 'silent do User ConnectionLost'.toupper(name[0]).name[1:]
+ elseif v:exception =~# 'E12'
+ " neovim's bug, ignore it
+ else
+ echohl Error | echo 'Error on request ('.a:method.'): '.v:exception | echohl None
+ endif
+ endtry
+endfunction
+
+function! s:notify(method, args) dict
+ let channel = coc#client#get_channel(self)
+ if empty(channel)
+ return ''
+ endif
+ try
+ if s:is_vim
+ call ch_sendraw(channel, json_encode([0, [a:method, a:args]])."\n")
+ else
+ call call('rpcnotify', [channel, a:method] + a:args)
+ endif
+ catch /.*/
+ if v:exception =~# 'E475'
+ if get(g:, 'coc_vim_leaving', 0)
+ return
+ endif
+ echohl Error | echom '['.self.name.'] server connection lost' | echohl None
+ let name = self.name
+ call s:on_exit(name, 0)
+ execute 'silent do User ConnectionLost'.toupper(name[0]).name[1:]
+ elseif v:exception =~# 'E12'
+ " neovim's bug, ignore it
+ else
+ echohl Error | echo 'Error on notify ('.a:method.'): '.v:exception | echohl None
+ endif
+ endtry
+endfunction
+
+function! s:request_async(method, args, cb) dict
+ let channel = coc#client#get_channel(self)
+ if empty(channel) | return '' | endif
+ if type(a:cb) != 2
+ echohl Error | echom '['.self['name'].'] Callback should be function' | echohl None
+ return
+ endif
+ let id = self.async_req_id
+ let self.async_req_id = id + 1
+ let self.async_callbacks[id] = a:cb
+ call self['notify']('nvim_async_request_event', [id, a:method, a:args])
+endfunction
+
+function! s:on_async_response(id, resp, isErr) dict
+ let Callback = get(self.async_callbacks, a:id, v:null)
+ if empty(Callback)
+ " should not happen
+ echohl Error | echom 'callback not found' | echohl None
+ return
+ endif
+ call remove(self.async_callbacks, a:id)
+ if a:isErr
+ call call(Callback, [a:resp, v:null])
+ else
+ call call(Callback, [v:null, a:resp])
+ endif
+endfunction
+
+function! coc#client#is_running(name) abort
+ let client = get(s:clients, a:name, v:null)
+ if empty(client) | return 0 | endif
+ if !client['running'] | return 0 | endif
+ if s:is_vim
+ let status = job_status(ch_getjob(client['channel']))
+ return status ==# 'run'
+ else
+ let chan_id = client['chan_id']
+ let [code] = jobwait([chan_id], 10)
+ return code == -1
+ endif
+endfunction
+
+function! coc#client#stop(name) abort
+ let client = get(s:clients, a:name, v:null)
+ if empty(client) | return 1 | endif
+ let running = coc#client#is_running(a:name)
+ if !running
+ echohl WarningMsg | echom 'client '.a:name. ' not running.' | echohl None
+ return 1
+ endif
+ if s:is_vim
+ call job_stop(ch_getjob(client['channel']), 'term')
+ else
+ call jobstop(client['chan_id'])
+ endif
+ sleep 200m
+ if coc#client#is_running(a:name)
+ echohl Error | echom 'client '.a:name. ' stop failed.' | echohl None
+ return 0
+ endif
+ call s:on_exit(a:name, 0)
+ echohl MoreMsg | echom 'client '.a:name.' stopped!' | echohl None
+ return 1
+endfunction
+
+function! coc#client#request(name, method, args)
+ let client = get(s:clients, a:name, v:null)
+ if !empty(client)
+ return client['request'](a:method, a:args)
+ endif
+endfunction
+
+function! coc#client#notify(name, method, args)
+ let client = get(s:clients, a:name, v:null)
+ if !empty(client)
+ call client['notify'](a:method, a:args)
+ endif
+endfunction
+
+function! coc#client#request_async(name, method, args, cb)
+ let client = get(s:clients, a:name, v:null)
+ if !empty(client)
+ call client['request_async'](a:method, a:args, a:cb)
+ endif
+endfunction
+
+function! coc#client#on_response(name, id, resp, isErr)
+ let client = get(s:clients, a:name, v:null)
+ if !empty(client)
+ call client['on_async_response'](a:id, a:resp, a:isErr)
+ endif
+endfunction
+
+function! coc#client#restart(name) abort
+ let stopped = coc#client#stop(a:name)
+ if !stopped | return | endif
+ let client = get(s:clients, a:name, v:null)
+ if !empty(client)
+ call client['start']()
+ endif
+endfunction
+
+function! coc#client#restart_all()
+ for key in keys(s:clients)
+ call coc#client#restart(key)
+ endfor
+endfunction
+
+function! coc#client#open_log()
+ if !get(g:, 'node_client_debug', 0)
+ echohl Error | echon '[coc.nvim] use let g:node_client_debug = 1 in your vimrc to enabled debug mode.' | echohl None
+ return
+ endif
+ execute 'vs '.s:logfile
+endfunction
diff --git a/private_dot_config/nvim/plugged/coc.nvim/autoload/coc/color.vim b/private_dot_config/nvim/plugged/coc.nvim/autoload/coc/color.vim
new file mode 100644
index 0000000..3ef527e
--- /dev/null
+++ b/private_dot_config/nvim/plugged/coc.nvim/autoload/coc/color.vim
@@ -0,0 +1,192 @@
+scriptencoding utf-8
+" Returns an approximate grey index for the given grey level
+fun! s:grey_number(x)
+ if &t_Co == 88
+ if a:x < 23
+ return 0
+ elseif a:x < 69
+ return 1
+ elseif a:x < 103
+ return 2
+ elseif a:x < 127
+ return 3
+ elseif a:x < 150
+ return 4
+ elseif a:x < 173
+ return 5
+ elseif a:x < 196
+ return 6
+ elseif a:x < 219
+ return 7
+ elseif a:x < 243
+ return 8
+ else
+ return 9
+ endif
+ else
+ if a:x < 14
+ return 0
+ else
+ let l:n = (a:x - 8) / 10
+ let l:m = (a:x - 8) % 10
+ if l:m < 5
+ return l:n
+ else
+ return l:n + 1
+ endif
+ endif
+ endif
+endfun
+
+" Returns the actual grey level represented by the grey index
+fun! s:grey_level(n)
+ if &t_Co == 88
+ if a:n == 0
+ return 0
+ elseif a:n == 1
+ return 46
+ elseif a:n == 2
+ return 92
+ elseif a:n == 3
+ return 115
+ elseif a:n == 4
+ return 139
+ elseif a:n == 5
+ return 162
+ elseif a:n == 6
+ return 185
+ elseif a:n == 7
+ return 208
+ elseif a:n == 8
+ return 231
+ else
+ return 255
+ endif
+ else
+ if a:n == 0
+ return 0
+ else
+ return 8 + (a:n * 10)
+ endif
+ endif
+endfun
+
+" Returns the palette index for the given grey index
+fun! s:grey_colour(n)
+ if &t_Co == 88
+ if a:n == 0
+ return 16
+ elseif a:n == 9
+ return 79
+ else
+ return 79 + a:n
+ endif
+ else
+ if a:n == 0
+ return 16
+ elseif a:n == 25
+ return 231
+ else
+ return 231 + a:n
+ endif
+ endif
+endfun
+
+" Returns an approximate colour index for the given colour level
+fun! s:rgb_number(x)
+ if &t_Co == 88
+ if a:x < 69
+ return 0
+ elseif a:x < 172
+ return 1
+ elseif a:x < 230
+ return 2
+ else
+ return 3
+ endif
+ else
+ if a:x < 75
+ return 0
+ else
+ let l:n = (a:x - 55) / 40
+ let l:m = (a:x - 55) % 40
+ if l:m < 20
+ return l:n
+ else
+ return l:n + 1
+ endif
+ endif
+ endif
+endfun
+
+" Returns the palette index for the given R/G/B colour indices
+fun! s:rgb_colour(x, y, z)
+ if &t_Co == 88
+ return 16 + (a:x * 16) + (a:y * 4) + a:z
+ else
+ return 16 + (a:x * 36) + (a:y * 6) + a:z
+ endif
+endfun
+
+" Returns the actual colour level for the given colour index
+fun! s:rgb_level(n)
+ if &t_Co == 88
+ if a:n == 0
+ return 0
+ elseif a:n == 1
+ return 139
+ elseif a:n == 2
+ return 205
+ else
+ return 255
+ endif
+ else
+ if a:n == 0
+ return 0
+ else
+ return 55 + (a:n * 40)
+ endif
+ endif
+endfun
+
+" Returns the palette index to approximate the given R/G/B colour levels
+fun! s:colour(r, g, b)
+ " Get the closest grey
+ let l:gx = s:grey_number(a:r)
+ let l:gy = s:grey_number(a:g)
+ let l:gz = s:grey_number(a:b)
+
+ " Get the closest colour
+ let l:x = s:rgb_number(a:r)
+ let l:y = s:rgb_number(a:g)
+ let l:z = s:rgb_number(a:b)
+
+ if l:gx == l:gy && l:gy == l:gz
+ " There are two possibilities
+ let l:dgr = s:grey_level(l:gx) - a:r
+ let l:dgg = s:grey_level(l:gy) - a:g
+ let l:dgb = s:grey_level(l:gz) - a:b
+ let l:dgrey = (l:dgr * l:dgr) + (l:dgg * l:dgg) + (l:dgb * l:dgb)
+ let l:dr = s:rgb_level(l:gx) - a:r
+ let l:dg = s:rgb_level(l:gy) - a:g
+ let l:db = s:rgb_level(l:gz) - a:b
+ let l:drgb = (l:dr * l:dr) + (l:dg * l:dg) + (l:db * l:db)
+ if l:dgrey < l:drgb
+ " Use the grey
+ return s:grey_colour(l:gx)
+ else
+ " Use the colour
+ return s:rgb_colour(l:x, l:y, l:z)
+ endif
+ else
+ " Only one possibility
+ return s:rgb_colour(l:x, l:y, l:z)
+ endif
+endfun
+
+function! coc#color#rgb2term(rgb)
+ let l:r = ("0x" . strpart(a:rgb, 0, 2)) + 0
+ let l:g = ("0x" . strpart(a:rgb, 2, 2)) + 0
+ let l:b = ("0x" . strpart(a:rgb, 4, 2)) + 0
+ return s:colour(l:r, l:g, l:b)
+endfun
diff --git a/private_dot_config/nvim/plugged/coc.nvim/autoload/coc/compat.vim b/private_dot_config/nvim/plugged/coc.nvim/autoload/coc/compat.vim
new file mode 100644
index 0000000..d53c109
--- /dev/null
+++ b/private_dot_config/nvim/plugged/coc.nvim/autoload/coc/compat.vim
@@ -0,0 +1,190 @@
+scriptencoding utf-8
+let s:is_vim = !has('nvim')
+
+" first window id for bufnr
+" builtin bufwinid returns window of current tab only
+function! coc#compat#buf_win_id(bufnr) abort
+ let info = filter(getwininfo(), 'v:val["bufnr"] =='.a:bufnr)
+ if empty(info)
+ return -1
+ endif
+ return info[0]['winid']
+endfunction
+
+function! coc#compat#buf_set_lines(bufnr, start, end, replacement) abort
+ if s:is_vim
+ call coc#api#notify('buf_set_lines', [a:bufnr, a:start, a:end, 0, a:replacement])
+ else
+ call nvim_buf_set_lines(a:bufnr, a:start, a:end, 0, a:replacement)
+ endif
+endfunction
+
+function! coc#compat#win_is_valid(winid) abort
+ if exists('*nvim_win_is_valid')
+ return nvim_win_is_valid(a:winid)
+ endif
+ return !empty(getwininfo(a:winid))
+endfunction
+
+" clear matches by window id, not throw on none exists window.
+" may not work on vim < 8.1.1084 & neovim < 0.4.0
+function! coc#compat#clear_matches(winid) abort
+ if !coc#compat#win_is_valid(a:winid)
+ return
+ endif
+ let curr = win_getid()
+ if curr == a:winid
+ call clearmatches()
+ return
+ endif
+ if s:is_vim
+ if has('patch-8.1.1084')
+ call clearmatches(a:winid)
+ endif
+ else
+ if exists('*nvim_set_current_win')
+ noa call nvim_set_current_win(a:winid)
+ call clearmatches()
+ noa call nvim_set_current_win(curr)
+ endif
+ endif
+endfunction
+
+function! coc#compat#matchaddpos(group, pos, priority, winid) abort
+ let curr = win_getid()
+ if curr == a:winid
+ call matchaddpos(a:group, a:pos, a:priority, -1)
+ else
+ if s:is_vim
+ if has('patch-8.1.0218')
+ call matchaddpos(a:group, a:pos, a:priority, -1, {'window': a:winid})
+ endif
+ else
+ if has('nvim-0.4.0')
+ call matchaddpos(a:group, a:pos, a:priority, -1, {'window': a:winid})
+ elseif exists('*nvim_set_current_win')
+ noa call nvim_set_current_win(a:winid)
+ call matchaddpos(a:group, a:pos, a:priority, -1)
+ noa call nvim_set_current_win(curr)
+ endif
+ endif
+ endif
+endfunction
+
+function! coc#compat#buf_del_var(bufnr, name) abort
+ if !bufloaded(a:bufnr)
+ return
+ endif
+ if exists('*nvim_buf_del_var')
+ silent! call nvim_buf_del_var(a:bufnr, a:name)
+ else
+ if bufnr == bufnr('%')
+ execute 'unlet! b:'.a:name
+ elseif exists('*win_execute')
+ let winid = coc#compat#buf_win_id(a:bufnr)
+ if winid != -1
+ call win_execute(winid, 'unlet! b:'.a:name)
+ endif
+ endif
+ endif
+endfunction
+
+" hlGroup, pos, priority
+function! coc#compat#matchaddgroups(winid, groups) abort
+ " add by winid
+ if has('patch-8.1.0218') || has('nvim-0.4.0')
+ for group in a:groups
+ call matchaddpos(group['hlGroup'], [group['pos']], group['priority'], -1, {'window': a:winid})
+ endfor
+ return
+ endif
+ let curr = win_getid()
+ if curr == a:winid
+ for group in a:groups
+ call matchaddpos(group['hlGroup'], [group['pos']], group['priority'], -1)
+ endfor
+ elseif exists('*nvim_set_current_win')
+ noa call nvim_set_current_win(a:winid)
+ for group in a:groups
+ call matchaddpos(group['hlGroup'], [group['pos']], group['priority'], -1)
+ endfor
+ noa call nvim_set_current_win(curr)
+ endif
+endfunction
+
+" remove keymap for specific buffer
+function! coc#compat#buf_del_keymap(bufnr, mode, lhs) abort
+ if !bufloaded(a:bufnr)
+ return
+ endif
+ if exists('*nvim_buf_del_keymap')
+ try
+ call nvim_buf_del_keymap(a:bufnr, a:mode, a:lhs)
+ catch /^Vim\%((\a\+)\)\=:E5555/
+ " ignore keymap not exists.
+ endtry
+ return
+ endif
+ if bufnr == a:bufnr
+ execute 'silent! '.a:mode.'unmap '.a:lhs
+ return
+ endif
+ if exists('*win_execute')
+ let winid = coc#compat#buf_win_id(a:bufnr)
+ if winid != -1
+ call win_execute(winid, 'silent! '.a:mode.'unmap '.a:lhs)
+ endif
+ endif
+endfunction
+
+function! coc#compat#buf_add_keymap(bufnr, mode, lhs, rhs, opts) abort
+ if !bufloaded(a:bufnr)
+ return
+ endif
+ if exists('*nvim_buf_set_keymap')
+ call nvim_buf_set_keymap(a:bufnr, a:mode, a:lhs, a:rhs, a:opts)
+ else
+ let cmd = a:mode . 'noremap '
+ for key in keys(a:opts)
+ if get(a:opts, key, 0)
+ let cmd .= '<'.key.'>'
+ endif
+ endfor
+ let cmd .= ' '.a:lhs.' '.a:rhs
+ if bufnr('%') == a:bufnr
+ execute cmd
+ elseif exists('*win_execute')
+ let winid = coc#compat#buf_win_id(a:bufnr)
+ if winid != -1
+ call win_execute(winid, cmd)
+ endif
+ endif
+ endif
+endfunction
+
+" execute command or list of commands in window
+function! coc#compat#execute(winid, command, ...) abort
+ if exists('*win_execute')
+ if type(a:command) == v:t_string
+ keepalt call win_execute(a:winid, a:command, get(a:, 1, ''))
+ elseif type(a:command) == v:t_list
+ keepalt call win_execute(a:winid, join(a:command, "\n"), get(a:, 1, ''))
+ endif
+ elseif has('nvim')
+ if !nvim_win_is_valid(a:winid)
+ return
+ endif
+ let curr = nvim_get_current_win()
+ noa keepalt call nvim_set_current_win(a:winid)
+ if type(a:command) == v:t_string
+ exe get(a:, 1, '').' '.a:command
+ elseif type(a:command) == v:t_list
+ for cmd in a:command
+ exe get(a:, 1, '').' '.cmd
+ endfor
+ endif
+ noa keepalt call nvim_set_current_win(curr)
+ else
+ throw 'win_execute not exists, please upgrade vim.'
+ endif
+endfunc
diff --git a/private_dot_config/nvim/plugged/coc.nvim/autoload/coc/cursor.vim b/private_dot_config/nvim/plugged/coc.nvim/autoload/coc/cursor.vim
new file mode 100644
index 0000000..f5ba66a
--- /dev/null
+++ b/private_dot_config/nvim/plugged/coc.nvim/autoload/coc/cursor.vim
@@ -0,0 +1,41 @@
+scriptencoding utf-8
+
+" Position of cursor relative to screen cell
+function! coc#cursor#screen_pos() abort
+ let nr = winnr()
+ let [row, col] = win_screenpos(nr)
+ return [row + winline() - 2, col + wincol() - 2]
+endfunction
+
+function! coc#cursor#move_by_col(delta)
+ let pos = getcurpos()
+ call cursor(pos[1], pos[2] + a:delta)
+endfunction
+
+" Get cursor position.
+function! coc#cursor#position()
+ return [line('.') - 1, strchars(strpart(getline('.'), 0, col('.') - 1))]
+endfunction
+
+" Move cursor to position.
+function! coc#cursor#move_to(line, character) abort
+ let content = getline(a:line + 1)
+ let pre = strcharpart(content, 0, a:character)
+ let col = strlen(pre) + 1
+ call cursor(a:line + 1, col)
+endfunction
+
+" Character offset of current cursor, vim provide bytes offset only.
+function! coc#cursor#char_offset() abort
+ let offset = 0
+ let lnum = line('.')
+ for i in range(1, lnum)
+ if i == lnum
+ let offset += strchars(strpart(getline('.'), 0, col('.')-1))
+ else
+ let offset += strchars(getline(i)) + 1
+ endif
+ endfor
+ return offset
+endfunction
+
diff --git a/private_dot_config/nvim/plugged/coc.nvim/autoload/coc/float.vim b/private_dot_config/nvim/plugged/coc.nvim/autoload/coc/float.vim
new file mode 100644
index 0000000..4d5801e
--- /dev/null
+++ b/private_dot_config/nvim/plugged/coc.nvim/autoload/coc/float.vim
@@ -0,0 +1,1866 @@
+scriptencoding utf-8
+let s:is_vim = !has('nvim')
+let s:root = expand(':h:h:h')
+let s:progresschars = get(g:, 'coc_progress_chars', ['░', '▇'])
+let s:borderchars = get(g:, 'coc_borderchars', ['─', '│', '─', '│', '┌', '┐', '┘', '└'])
+let s:borderjoinchars = get(g:, 'coc_border_joinchars', ['┬', '┤', '┴', '├'])
+let s:prompt_win_width = get(g:, 'coc_prompt_win_width', 32)
+let s:prompt_win_bufnr = 0
+let s:float_supported = exists('*nvim_open_win') || has('patch-8.1.1719')
+let s:popup_list_api = exists('*popup_list')
+" Popup ids, used when popup_list() not exists
+let s:popup_list = []
+" winvar: border array of numbers, button boolean
+
+" Check visible float/popup exists.
+function! coc#float#has_float(...) abort
+ return len(coc#float#get_float_win_list(get(a:, 1, 0))) > 0
+endfunction
+
+function! coc#float#close_all(...) abort
+ let winids = coc#float#get_float_win_list(get(a:, 1, 0))
+ for id in winids
+ try
+ call coc#float#close(id)
+ catch /E5555:/
+ " ignore
+ endtry
+ endfor
+endfunction
+
+function! coc#float#jump() abort
+ if s:is_vim
+ return
+ endif
+ let winids = coc#float#get_float_win_list()
+ if !empty(winids)
+ call win_gotoid(winids[0])
+ endif
+endfunction
+
+" create or config float window, returns [winid, bufnr], config including:
+" - relative: could be 'editor' 'cursor'
+" - row: line count relative to editor/cursor, nagetive number means abover cursor.
+" - col: column count relative to editor/cursor, nagetive number means left of cursor.
+" - width: content width without border and title.
+" - height: content height without border and title.
+" - lines: (optional) lines to insert, default to v:null.
+" - title: (optional) title.
+" - border: (optional) border as number list, like [1, 1, 1 ,1].
+" - cursorline: (optional) enable cursorline when is 1.
+" - autohide: (optional) window should be closed on CursorMoved when is 1.
+" - highlight: (optional) highlight of window, default to 'CocFloating'
+" - borderhighlight: (optional) should be array for border highlights,
+" highlight all borders with first value.
+" - close: (optional) show close button when is 1.
+" - buttons: (optional) array of button text for create buttons at bottom.
+" - codes: (optional) list of CodeBlock.
+" - winblend: winblend option for float window, neovim only.
+" - shadow: use shadow as border style, neovim only.
+" - focusable: neovim only, default to true.
+function! coc#float#create_float_win(winid, bufnr, config) abort
+ let lines = get(a:config, 'lines', v:null)
+ let bufnr = coc#float#create_buf(a:bufnr, lines, 'hide')
+ " use exists
+ if a:winid && coc#float#valid(a:winid)
+ if s:is_vim
+ let [line, col] = s:popup_position(a:config)
+ let opts = {
+ \ 'firstline': 1,
+ \ 'line': line,
+ \ 'col': col,
+ \ 'minwidth': a:config['width'],
+ \ 'minheight': a:config['height'],
+ \ 'maxwidth': a:config['width'],
+ \ 'maxheight': a:config['height'],
+ \ 'cursorline': get(a:config, 'cursorline', 0),
+ \ 'title': get(a:config, 'title', ''),
+ \ }
+ if !s:empty_border(get(a:config, 'border', []))
+ let opts['border'] = a:config['border']
+ endif
+ call popup_setoptions(a:winid, opts)
+ call coc#float#vim_buttons(a:winid, a:config)
+ call s:add_highlights(a:winid, a:config, 0)
+ return [a:winid, winbufnr(a:winid)]
+ else
+ let config = s:convert_config_nvim(a:config)
+ call nvim_win_set_buf(a:winid, bufnr)
+ call nvim_win_set_config(a:winid, config)
+ call nvim_win_set_cursor(a:winid, [1, 0])
+ call coc#float#nvim_create_related(a:winid, config, a:config)
+ call s:add_highlights(a:winid, a:config, 0)
+ return [a:winid, bufnr]
+ endif
+ endif
+ let winid = 0
+ if s:is_vim
+ let [line, col] = s:popup_position(a:config)
+ let title = get(a:config, 'title', '')
+ let buttons = get(a:config, 'buttons', [])
+ let hlgroup = get(a:config, 'highlight', 'CocFloating')
+ let opts = {
+ \ 'title': title,
+ \ 'line': line,
+ \ 'col': col,
+ \ 'fixed': 1,
+ \ 'padding': empty(title) ? [0, 1, 0, 1] : [0, 0, 0, 0],
+ \ 'borderchars': s:borderchars,
+ \ 'highlight': hlgroup,
+ \ 'cursorline': get(a:config, 'cursorline', 0),
+ \ 'minwidth': a:config['width'],
+ \ 'minheight': a:config['height'],
+ \ 'maxwidth': a:config['width'],
+ \ 'maxheight': a:config['height']
+ \ }
+ if get(a:config, 'close', 0)
+ let opts['close'] = 'button'
+ endif
+ if !empty(get(a:config, 'borderhighlight', v:null))
+ let borderhighlight = a:config['borderhighlight']
+ let opts['borderhighlight'] = type(borderhighlight) == 3
+ \ ? map(borderhighlight, 'coc#highlight#compose_hlgroup(v:val,"'.hlgroup.'")')
+ \ : [coc#highlight#compose_hlgroup(borderhighlight, hlgroup)]
+ endif
+ if !s:empty_border(get(a:config, 'border', []))
+ let opts['border'] = a:config['border']
+ endif
+ let winid = popup_create(bufnr, opts)
+ if !s:popup_list_api
+ call add(s:popup_list, winid)
+ endif
+ if winid == 0
+ return []
+ endif
+ call coc#float#vim_buttons(winid, a:config)
+ if has("patch-8.1.2281")
+ call setwinvar(winid, '&showbreak', 'NONE')
+ endif
+ else
+ let config = s:convert_config_nvim(a:config)
+ let border = get(a:config, 'border', [])
+ if has('nvim-0.5.0') && get(a:config, 'shadow', 0) && empty(get(a:config, 'buttons', v:null)) && empty(get(border, 2, 0))
+ let config['border'] = 'shadow'
+ endif
+ noa let winid = nvim_open_win(bufnr, 0, config)
+ if winid == 0
+ return []
+ endif
+ let hlgroup = get(a:config, 'highlight', 'CocFloating')
+ call setwinvar(winid, '&winhl', 'Normal:'.hlgroup.',NormalNC:'.hlgroup.',FoldColumn:'.hlgroup)
+ call setwinvar(winid, '&signcolumn', 'no')
+ call setwinvar(winid, '&foldenable', 0)
+ " cursorline highlight not work on old neovim
+ call setwinvar(winid, '&cursorline', 0)
+ call setwinvar(winid, 'border', get(a:config, 'border', []))
+ if get(a:config, 'winblend', 0)
+ call setwinvar(winid, '&winblend', a:config['winblend'])
+ endif
+ " no left border
+ if s:empty_border(get(a:config, 'border', [])) || a:config['border'][3] == 0
+ call setwinvar(winid, '&foldcolumn', 1)
+ else
+ call setwinvar(winid, '&foldcolumn', 0)
+ endif
+ call nvim_win_set_cursor(winid, [1, 0])
+ call coc#float#nvim_create_related(winid, config, a:config)
+ endif
+ if get(a:config, 'autohide', 0)
+ call setwinvar(winid, 'autohide', 1)
+ endif
+ if s:is_vim || has('nvim-0.5.0')
+ call setwinvar(winid, '&scrolloff', 0)
+ endif
+ call setwinvar(winid, 'float', 1)
+ call setwinvar(winid, '&list', 0)
+ call setwinvar(winid, '&number', 0)
+ call setwinvar(winid, '&relativenumber', 0)
+ call setwinvar(winid, '&cursorcolumn', 0)
+ call setwinvar(winid, '&colorcolumn', 0)
+ call setwinvar(winid, '&wrap', 1)
+ call setwinvar(winid, '&linebreak', 1)
+ call setwinvar(winid, '&conceallevel', 0)
+ call s:add_highlights(winid, a:config, 0)
+ let g:coc_last_float_win = winid
+ call coc#util#do_autocmd('CocOpenFloat')
+ return [winid, bufnr]
+endfunction
+
+function! coc#float#valid(winid) abort
+ if a:winid <= 0
+ return 0
+ endif
+ if has('nvim')
+ return nvim_win_is_valid(a:winid) ? 1 : 0
+ endif
+ return s:popup_visible(a:winid)
+endfunction
+
+function! coc#float#nvim_create_related(winid, config, opts) abort
+ let related = getwinvar(a:winid, 'related', [])
+ let exists = !empty(related)
+ let border = get(a:opts, 'border', [])
+ let highlights = get(a:opts, 'borderhighlight', [])
+ let hlgroup = get(a:opts, 'highlight', 'CocFloating')
+ let borderhighlight = type(highlights) == 1 ? highlights : get(highlights, 0, 'CocFloating')
+ let borderhighlight = coc#highlight#compose_hlgroup(borderhighlight, hlgroup)
+ let title = get(a:opts, 'title', '')
+ let buttons = get(a:opts, 'buttons', [])
+ let pad = empty(border) || get(border, 1, 0) == 0
+ let winblend = get(a:opts, 'winblend', 0)
+ let shadow = get(a:opts, 'shadow', 0)
+ if get(a:opts, 'close', 0)
+ call coc#float#nvim_close_btn(a:config, a:winid, border, borderhighlight, winblend, related)
+ elseif exists
+ call coc#float#close_related(a:winid, 'close')
+ endif
+ if !empty(buttons)
+ call coc#float#nvim_buttons(a:config, a:winid, buttons, get(border, 2, 0), pad, hlgroup, borderhighlight, winblend, shadow, related)
+ elseif exists
+ call coc#float#close_related(a:winid, 'buttons')
+ endif
+ if !s:empty_border(border)
+ call coc#float#nvim_border_win(a:config, a:winid, border, title, !empty(buttons), borderhighlight, winblend, shadow, related)
+ elseif exists
+ call coc#float#close_related(a:winid, 'border')
+ endif
+ " Check right border
+ if pad
+ call coc#float#nvim_right_pad(a:config, a:winid, hlgroup, winblend, related)
+ elseif exists
+ call coc#float#close_related(a:winid, 'pad')
+ endif
+ call setwinvar(a:winid, 'related', filter(related, 'nvim_win_is_valid(v:val)'))
+endfunction
+
+" border window for neovim, content config with border
+function! coc#float#nvim_border_win(config, winid, border, title, hasbtn, hlgroup, winblend, shadow, related) abort
+ let winid = coc#float#get_related(a:winid, 'border')
+ let row = a:border[0] ? a:config['row'] - 1 : a:config['row']
+ let col = a:border[3] ? a:config['col'] - 1 : a:config['col']
+ let width = a:config['width'] + a:border[1] + a:border[3]
+ let height = a:config['height'] + a:border[0] + a:border[2] + (a:hasbtn ? 2 : 0)
+ let lines = coc#float#create_border_lines(a:border, a:title, a:config['width'], a:config['height'], a:hasbtn)
+ let bufnr = winid ? winbufnr(winid) : 0
+ let bufnr = coc#float#create_buf(bufnr, lines)
+ let opt = {
+ \ 'relative': a:config['relative'],
+ \ 'width': width,
+ \ 'height': height,
+ \ 'row': row,
+ \ 'col': col,
+ \ 'focusable': v:false,
+ \ 'style': 'minimal',
+ \ }
+ if has('nvim-0.5.0') && a:shadow && !a:hasbtn && a:border[2]
+ let opt['border'] = 'shadow'
+ endif
+ if winid
+ call nvim_win_set_config(winid, opt)
+ call setwinvar(winid, '&winhl', 'Normal:'.a:hlgroup.',NormalNC:'.a:hlgroup)
+ else
+ noa let winid = nvim_open_win(bufnr, 0, opt)
+ if winid
+ if a:winblend
+ call setwinvar(winid, '&winblend', a:winblend)
+ endif
+ call setwinvar(winid, '&winhl', 'Normal:'.a:hlgroup.',NormalNC:'.a:hlgroup)
+ call setwinvar(winid, 'target_winid', a:winid)
+ call setwinvar(winid, 'kind', 'border')
+ call add(a:related, winid)
+ endif
+ endif
+endfunction
+
+" neovim only
+function! coc#float#nvim_close_btn(config, winid, border, hlgroup, winblend, related) abort
+ let winid = coc#float#get_related(a:winid, 'close')
+ let config = {
+ \ 'relative': a:config['relative'],
+ \ 'width': 1,
+ \ 'height': 1,
+ \ 'row': get(a:border, 0, 0) ? a:config['row'] - 1 : a:config['row'],
+ \ 'col': a:config['col'] + a:config['width'],
+ \ 'focusable': v:true,
+ \ 'style': 'minimal',
+ \ }
+ if has('nvim-0.5.0')
+ let config['zindex'] = 300
+ endif
+ if winid
+ call nvim_win_set_config(winid, config)
+ else
+ let bufnr = coc#float#create_buf(0, ['X'])
+ noa let winid = nvim_open_win(bufnr, 0, config)
+ if winid
+ call setwinvar(winid, '&winhl', 'Normal:'.a:hlgroup.',NormalNC:'.a:hlgroup)
+ call setwinvar(winid, 'target_winid', a:winid)
+ call setwinvar(winid, 'kind', 'close')
+ if a:winblend
+ call setwinvar(winid, '&winblend', a:winblend)
+ endif
+ call add(a:related, winid)
+ endif
+ call s:nvim_create_keymap(winid)
+ endif
+endfunction
+
+" Create padding window by config of current window & border config
+function! coc#float#nvim_right_pad(config, winid, hlgroup, winblend, related) abort
+ let winid = coc#float#get_related(a:winid, 'pad')
+ let bufnr = 0
+ let config = {
+ \ 'relative': a:config['relative'],
+ \ 'width': 1,
+ \ 'height': a:config['height'],
+ \ 'row': a:config['row'],
+ \ 'col': a:config['col'] + a:config['width'],
+ \ 'focusable': v:false,
+ \ 'style': 'minimal',
+ \ }
+ if has('nvim-0.5.0')
+ let config['zindex'] = 300
+ endif
+ if winid && nvim_win_is_valid(winid)
+ let bufnr = nvim_win_get_buf(winid)
+ noa call nvim_win_close(winid, 1)
+ endif
+ let bufnr = coc#float#create_buf(bufnr, repeat([''], a:config['height']))
+ noa let winid = nvim_open_win(bufnr, 0, config)
+ if winid
+ " minimal not work
+ if !has('nvim-0.4.3')
+ call setwinvar(winid, '&colorcolumn', 0)
+ call setwinvar(winid, '&number', 0)
+ call setwinvar(winid, '&relativenumber', 0)
+ call setwinvar(winid, '&foldcolumn', 0)
+ call setwinvar(winid, '&signcolumn', 0)
+ endif
+ if a:winblend
+ call setwinvar(winid, '&winblend', a:winblend)
+ endif
+ call setwinvar(winid, '&winhl', 'Normal:'.a:hlgroup.',NormalNC:'.a:hlgroup)
+ call setwinvar(winid, 'target_winid', a:winid)
+ call setwinvar(winid, 'kind', 'pad')
+ call add(a:related, winid)
+ endif
+endfunction
+
+" draw buttons window for window with config
+function! coc#float#nvim_buttons(config, winid, buttons, borderbottom, pad, hlgroup, borderhighlight, winblend, shadow, related) abort
+ let winid = coc#float#get_related(a:winid, 'buttons')
+ let width = a:config['width'] + (a:pad ? 1 : 0)
+ let config = {
+ \ 'row': a:config['row'] + a:config['height'],
+ \ 'col': a:config['col'],
+ \ 'width': width,
+ \ 'height': 2 + (a:borderbottom ? 1 : 0),
+ \ 'relative': a:config['relative'],
+ \ 'focusable': 1,
+ \ 'style': 'minimal',
+ \ }
+ if has('nvim-0.5.0')
+ let config['zindex'] = 300
+ if a:shadow
+ let config['border'] = 'shadow'
+ endif
+ endif
+ if winid
+ let bufnr = winbufnr(winid)
+ call s:create_btns_buffer(bufnr, width, a:buttons, a:borderbottom)
+ call nvim_win_set_config(winid, config)
+ else
+ let bufnr = s:create_btns_buffer(0, width, a:buttons, a:borderbottom)
+ noa let winid = nvim_open_win(bufnr, 0, config)
+ if winid
+ call setwinvar(winid, '&winhl', 'Normal:'.a:hlgroup.',NormalNC:'.a:hlgroup)
+ call setwinvar(winid, 'target_winid', a:winid)
+ call setwinvar(winid, 'kind', 'buttons')
+ if a:winblend
+ call setwinvar(winid, '&winblend', a:winblend)
+ endif
+ call add(a:related, winid)
+ call s:nvim_create_keymap(winid)
+ endif
+ endif
+ if bufnr && a:hlgroup != a:borderhighlight
+ call nvim_buf_clear_namespace(bufnr, -1, 0, -1)
+ call nvim_buf_add_highlight(bufnr, 1, a:borderhighlight, 0, 0, -1)
+ if a:borderbottom
+ call nvim_buf_add_highlight(bufnr, 1, a:borderhighlight, 2, 0, -1)
+ endif
+ let vcols = getbufvar(bufnr, 'vcols', [])
+ " TODO need change vol to col
+ for col in vcols
+ call nvim_buf_add_highlight(bufnr, 1, a:borderhighlight, 1, col, col + 3)
+ endfor
+ endif
+endfunction
+
+" Create or refresh scrollbar for winid
+" Need called on create, config, buffer change, scrolled
+function! coc#float#nvim_scrollbar(winid) abort
+ if !has('nvim-0.4.0') || getwinvar(a:winid, 'target_winid', 0)
+ return
+ endif
+ let winids = nvim_tabpage_list_wins(nvim_get_current_tabpage())
+ if index(winids, a:winid) == -1
+ return
+ endif
+ let config = nvim_win_get_config(a:winid)
+ let [row, column] = nvim_win_get_position(a:winid)
+ let relative = 'editor'
+ if row == 0 && column == 0
+ " fix bad value when ext_multigrid is enabled. https://github.com/neovim/neovim/issues/11935
+ let [row, column] = [config.row, config.col]
+ let relative = config.relative
+ endif
+ let width = nvim_win_get_width(a:winid)
+ let height = nvim_win_get_height(a:winid)
+ let bufnr = winbufnr(a:winid)
+ let cw = getwinvar(a:winid, '&foldcolumn', 0) ? width - 1 : width
+ let ch = coc#float#content_height(bufnr, cw, getwinvar(a:winid, '&wrap'))
+ let closewin = coc#float#get_related(a:winid, 'close')
+ let border = getwinvar(a:winid, 'border', [])
+ let winblend = getwinvar(a:winid, '&winblend', 0)
+ let move_down = closewin && !get(border, 0, 0)
+ let id = coc#float#get_related(a:winid, 'scrollbar')
+ if ch <= height || height <= 1
+ " no scrollbar, remove exists
+ if id
+ call s:close_win(id)
+ endif
+ return
+ endif
+ if move_down
+ let height = height - 1
+ endif
+ call coc#float#close_related(a:winid, 'pad')
+ let sbuf = id ? winbufnr(id) : 0
+ let sbuf = coc#float#create_buf(sbuf, repeat([' '], height))
+ let opts = {
+ \ 'row': move_down ? row + 1 : row,
+ \ 'col': column + width,
+ \ 'relative': relative,
+ \ 'width': 1,
+ \ 'height': height,
+ \ 'focusable': v:false,
+ \ 'style': 'minimal',
+ \ }
+ if has('nvim-0.5.0')
+ let opts['zindex'] = 300
+ endif
+ if id
+ call nvim_win_set_config(id, opts)
+ else
+ noa let id = nvim_open_win(sbuf, 0 , opts)
+ if id == 0
+ return
+ endif
+ if winblend
+ call setwinvar(id, '&winblend', winblend)
+ endif
+ call setwinvar(id, 'kind', 'scrollbar')
+ call setwinvar(id, 'target_winid', a:winid)
+ call s:add_related(id, a:winid)
+ endif
+ call coc#float#nvim_scroll_adjust(a:winid)
+ let thumb_height = max([1, float2nr(floor(height * (height + 0.0)/ch))])
+ let wininfo = getwininfo(a:winid)[0]
+ let start = 0
+ if wininfo['topline'] != 1
+ " needed for correct getwininfo
+ let firstline = wininfo['topline']
+ let lastline = s:nvim_get_botline(firstline, height, cw, bufnr)
+ let linecount = nvim_buf_line_count(winbufnr(a:winid))
+ if lastline >= linecount
+ let start = height - thumb_height
+ else
+ let start = max([1, float2nr(round((height - thumb_height + 0.0)*(firstline - 1.0)/(ch - height)))])
+ endif
+ endif
+ " add highlights
+ call nvim_buf_clear_namespace(sbuf, -1, 0, -1)
+ for idx in range(0, height - 1)
+ if idx >= start && idx < start + thumb_height
+ call nvim_buf_add_highlight(sbuf, -1, 'PmenuThumb', idx, 0, 1)
+ else
+ call nvim_buf_add_highlight(sbuf, -1, 'PmenuSbar', idx, 0, 1)
+ endif
+ endfor
+endfunction
+
+function! coc#float#create_border_lines(border, title, width, height, hasbtn) abort
+ let list = []
+ if a:border[0]
+ let top = (a:border[3] ? s:borderchars[4]: '')
+ \.repeat(s:borderchars[0], a:width)
+ \.(a:border[1] ? s:borderchars[5] : '')
+ if !empty(a:title)
+ let top = coc#helper#str_compose(top, 1, a:title.' ')
+ endif
+ call add(list, top)
+ endif
+ let mid = (a:border[3] ? s:borderchars[3]: '')
+ \.repeat(' ', a:width)
+ \.(a:border[1] ? s:borderchars[1] : '')
+ call extend(list, repeat([mid], a:height + (a:hasbtn ? 2 : 0)))
+ if a:hasbtn
+ let list[len(list) - 2] = (a:border[3] ? s:borderjoinchars[3]: '')
+ \.repeat(' ', a:width)
+ \.(a:border[1] ? s:borderjoinchars[1] : '')
+ endif
+ if a:border[2]
+ let bot = (a:border[3] ? s:borderchars[7]: '')
+ \.repeat(s:borderchars[2], a:width)
+ \.(a:border[1] ? s:borderchars[6] : '')
+ call add(list, bot)
+ endif
+ return list
+endfunction
+
+" Get config, convert lines, create window, add highlights
+function! coc#float#create_cursor_float(winid, bufnr, lines, config) abort
+ if !s:float_supported
+ return v:null
+ endif
+ if s:is_blocking()
+ return v:null
+ endif
+ let pumAlignTop = get(a:config, 'pumAlignTop', 0)
+ let modes = get(a:config, 'modes', ['n', 'i', 'ic', 's'])
+ let mode = mode()
+ let currbuf = bufnr('%')
+ let pos = [line('.'), col('.')]
+ if index(modes, mode) == -1
+ return v:null
+ endif
+ if has('nvim') && mode ==# 'i'
+ " helps to fix undo issue, don't know why.
+ call feedkeys("\u", 'n')
+ endif
+ let dimension = coc#float#get_config_cursor(a:lines, a:config)
+ if empty(dimension)
+ return v:null
+ endif
+ if pumvisible() && ((pumAlignTop && dimension['row'] <0)|| (!pumAlignTop && dimension['row'] > 0))
+ return v:null
+ endif
+ let width = dimension['width']
+ let lines = map(a:lines, {_, s -> s =~# '^─' ? repeat('─', width) : s})
+ let config = extend(extend({'lines': lines, 'relative': 'cursor'}, a:config), dimension)
+ call coc#float#close_auto_hide_wins(a:winid)
+ let res = coc#float#create_float_win(a:winid, a:bufnr, config)
+ if empty(res)
+ return v:null
+ endif
+ let alignTop = dimension['row'] < 0
+ let winid = res[0]
+ let bufnr = res[1]
+ redraw
+ if has('nvim')
+ call coc#float#nvim_scrollbar(winid)
+ endif
+ return [currbuf, pos, winid, bufnr, alignTop]
+endfunction
+
+" Create float window for input
+function! coc#float#create_prompt_win(title, default, opts) abort
+ call coc#float#close_auto_hide_wins()
+ " Calculate col
+ let curr = win_screenpos(winnr())[1] + wincol() - 2
+ let width = coc#helper#min(max([strdisplaywidth(a:default) + 2, s:prompt_win_width]), &columns - 2)
+ if width == &columns - 2
+ let col = 0 - curr
+ else
+ let col = curr + width <= &columns - 2 ? 0 : &columns - s:prompt_win_width
+ endif
+ let [lineIdx, colIdx] = coc#cursor#screen_pos()
+ let bufnr = 0
+ if has('nvim')
+ let bufnr = s:prompt_win_bufnr
+ else
+ execute 'hi link CocPopupTerminal '.get(a:opts, 'highlight', 'CocFloating')
+ let node = expand(get(g:, 'coc_node_path', 'node'))
+ let bufnr = term_start([node, s:root . '/bin/prompt.js', a:default], {
+ \ 'term_highlight': 'CocPopupTerminal',
+ \ 'hidden': 1,
+ \ 'term_finish': 'close'
+ \ })
+ call term_setapi(bufnr, "Coc")
+ endif
+ let res = coc#float#create_float_win(0, bufnr, {
+ \ 'relative': 'cursor',
+ \ 'row': lineIdx == 0 ? 1 : 0,
+ \ 'col': colIdx == 0 ? 0 : col - 1,
+ \ 'width': width,
+ \ 'height': 1,
+ \ 'style': 'minimal',
+ \ 'border': [1,1,1,1],
+ \ 'prompt': 1,
+ \ 'title': a:title,
+ \ 'lines': s:is_vim ? v:null : [a:default],
+ \ 'highlight': get(a:opts, 'highlight', 'CocFloating'),
+ \ 'borderhighlight': [get(a:opts, 'borderhighlight', 'CocFloating')],
+ \ })
+ if empty(res) || res[0] == 0
+ return
+ endif
+ let winid = res[0]
+ let bufnr = res[1]
+ if has('nvim')
+ let s:prompt_win_bufnr = res[1]
+ execute 'sign unplace 6 buffer='.s:prompt_win_bufnr
+ call nvim_set_current_win(winid)
+ inoremap
+ inoremap pumvisible() ? "\" : "\"
+ exe 'imap '
+ exe 'nnoremap :call coc#float#close('.winid.')'
+ exe 'inoremap "\=coc#float#prompt_insert(getline(''.''))\\"'
+ call feedkeys('A', 'in')
+ endif
+ return [bufnr, winid]
+endfunction
+
+function! coc#float#prompt_insert(text) abort
+ call coc#rpc#notify('PromptInsert', [a:text])
+ return ''
+endfunction
+
+" Close float window by id
+function! coc#float#close(winid) abort
+ call coc#float#close_related(a:winid)
+ call s:close_win(a:winid)
+ return 1
+endfunction
+
+" Float window id on current tab.
+" return 0 if not found, used by test only
+function! coc#float#get_float_win() abort
+ if has('nvim')
+ for i in range(1, winnr('$'))
+ let id = win_getid(i)
+ let config = nvim_win_get_config(id)
+ if (!empty(config) && config['focusable'] == v:true && !empty(config['relative']))
+ if !getwinvar(id, 'button', 0)
+ return id
+ endif
+ endif
+ endfor
+ else
+ let ids = s:popup_list_api ? popup_list() : s:popup_list
+ return get(filter(ids, 's:popup_visible(v:val)'), 0, 0)
+ endif
+ return 0
+endfunction
+
+function! coc#float#get_float_win_list(...) abort
+ let res = []
+ let all = get(a:, 1, 0)
+ if s:is_vim
+ if s:popup_list_api
+ return filter(popup_list(), 'popup_getpos(v:val)["visible"]'.(all ? '' : '&& getwinvar(v:val, "float", 0)'))
+ endif
+ return filter(s:popup_list, 's:popup_visible(v:val)')
+ elseif has('nvim') && exists('*nvim_win_get_config')
+ let res = []
+ for i in range(1, winnr('$'))
+ let id = win_getid(i)
+ let config = nvim_win_get_config(id)
+ if empty(config) || empty(config['relative'])
+ continue
+ endif
+ " ignore border & button window & others
+ if !all && !getwinvar(id, 'float', 0)
+ continue
+ endif
+ call add(res, id)
+ endfor
+ return res
+ endif
+ return []
+endfunction
+
+" Check if a float window is scrollable
+function! coc#float#scrollable(winid) abort
+ let bufnr = winbufnr(a:winid)
+ if bufnr == -1
+ return 0
+ endif
+ if s:is_vim
+ let pos = popup_getpos(a:winid)
+ if get(popup_getoptions(a:winid), 'scrollbar', 0)
+ return get(pos, 'scrollbar', 0)
+ endif
+ let ch = coc#float#content_height(bufnr, pos['core_width'], getwinvar(a:winid, '&wrap'))
+ return ch > pos['core_height']
+ else
+ let height = nvim_win_get_height(a:winid)
+ let width = nvim_win_get_width(a:winid)
+ if width > 1 && getwinvar(a:winid, '&foldcolumn', 0)
+ " since we use foldcolumn for left pading
+ let width = width - 1
+ endif
+ let ch = coc#float#content_height(bufnr, width, getwinvar(a:winid, '&wrap'))
+ return ch > height
+ endif
+endfunction
+
+function! coc#float#has_scroll() abort
+ let win_ids = filter(coc#float#get_float_win_list(), 'coc#float#scrollable(v:val)')
+ return !empty(win_ids)
+endfunction
+
+function! coc#float#scroll(forward, ...)
+ if !has('nvim-0.4.0') && !has('patch-8.2.0750')
+ throw 'coc#float#scroll() requires nvim >= 0.4.0 or vim >= 8.2.0750'
+ endif
+ let amount = get(a:, 1, 0)
+ let winids = filter(coc#float#get_float_win_list(), 'coc#float#scrollable(v:val)')
+ if empty(winids)
+ return ''
+ endif
+ for winid in winids
+ if s:is_vim
+ call coc#float#scroll_win(winid, a:forward, amount)
+ else
+ call timer_start(0, { -> coc#float#scroll_win(winid, a:forward, amount)})
+ endif
+ endfor
+ return mode() =~ '^i' || mode() ==# 'v' ? "" : "\"
+endfunction
+
+function! coc#float#scroll_win(winid, forward, amount) abort
+ let opts = s:get_options(a:winid)
+ let lines = getbufline(winbufnr(a:winid), 1, '$')
+ let maxfirst = s:max_firstline(lines, opts['height'], opts['width'])
+ let topline = opts['topline']
+ let height = opts['height']
+ let width = opts['width']
+ let scrolloff = getwinvar(a:winid, '&scrolloff', 0)
+ if a:forward && topline >= maxfirst
+ return
+ endif
+ if !a:forward && topline == 1
+ return
+ endif
+ if a:amount == 0
+ let topline = s:get_topline(opts['topline'], lines, a:forward, height, width)
+ else
+ let topline = topline + (a:forward ? a:amount : - a:amount)
+ endif
+ let topline = a:forward ? min([maxfirst, topline]) : max([1, topline])
+ let lnum = s:get_cursorline(topline, lines, scrolloff, width, height)
+ call s:win_setview(a:winid, topline, lnum)
+ let top = s:get_options(a:winid)['topline']
+ " not changed
+ if top == opts['topline']
+ if a:forward
+ call s:win_setview(a:winid, topline + 1, lnum + 1)
+ else
+ call s:win_setview(a:winid, topline - 1, lnum - 1)
+ endif
+ endif
+endfunction
+
+function! s:popup_visible(id) abort
+ let pos = popup_getpos(a:id)
+ if !empty(pos) && get(pos, 'visible', 0)
+ return 1
+ endif
+ return 0
+endfunction
+
+function! s:convert_config_nvim(config) abort
+ let valids = ['relative', 'win', 'anchor', 'width', 'height', 'bufpos', 'col', 'row', 'focusable', 'style']
+ let result = coc#helper#dict_pick(a:config, valids)
+ let border = get(a:config, 'border', [])
+ if !s:empty_border(border)
+ if result['relative'] ==# 'cursor' && result['row'] < 0
+ " move top when has bottom border
+ if get(border, 2, 0)
+ let result['row'] = result['row'] - 1
+ endif
+ else
+ " move down when has top border
+ if get(border, 0, 0) && !get(a:config, 'prompt', 0)
+ let result['row'] = result['row'] + 1
+ endif
+ endif
+ " move right when has left border
+ if get(border, 3, 0)
+ let result['col'] = result['col'] + 1
+ endif
+ let result['width'] = float2nr(result['width'] + 1 - get(border,3, 0))
+ else
+ let result['width'] = float2nr(result['width'] + 1)
+ endif
+ let result['height'] = float2nr(result['height'])
+ return result
+endfunction
+
+" Close windows that could auto hide
+function! coc#float#close_auto_hide_wins(...) abort
+ let winids = coc#float#get_float_win_list()
+ let except = get(a:, 1, 0)
+ for id in winids
+ if except && id == except
+ continue
+ endif
+ if getwinvar(id, 'autohide', 0)
+ call coc#float#close(id)
+ endif
+ endfor
+endfunction
+
+function! coc#float#content_height(bufnr, width, wrap) abort
+ if !bufloaded(a:bufnr)
+ return 0
+ endif
+ if !a:wrap
+ return has('nvim') ? nvim_buf_line_count(a:bufnr) : len(getbufline(a:bufnr, 1, '$'))
+ endif
+ let lines = has('nvim') ? nvim_buf_get_lines(a:bufnr, 0, -1, 0) : getbufline(a:bufnr, 1, '$')
+ let total = 0
+ for line in lines
+ let dw = max([1, strdisplaywidth(line)])
+ let total += float2nr(ceil(str2float(string(dw))/a:width))
+ endfor
+ return total
+endfunction
+
+function! coc#float#nvim_refresh_scrollbar(winid) abort
+ let id = coc#float#get_related(a:winid, 'scrollbar')
+ if id && nvim_win_is_valid(id)
+ call coc#float#nvim_scrollbar(a:winid)
+ endif
+endfunction
+
+" Close related windows, or specific kind
+function! coc#float#close_related(winid, ...) abort
+ let tabnr = coc#window#tabnr(a:winid)
+ if tabnr != -1
+ let timer = gettabwinvar(tabnr, a:winid, 'timer', 0)
+ if timer
+ call timer_stop(timer)
+ endif
+ let kind = get(a:, 1, '')
+ let winids = gettabwinvar(tabnr, a:winid, 'related', [])
+ for id in winids
+ if s:is_vim
+ " vim doesn't throw
+ noa call popup_close(id)
+ else
+ if empty(kind) || gettabwinvar(tabnr, id, 'kind', '') ==# kind
+ if nvim_win_is_valid(id)
+ noa call nvim_win_close(id, 1)
+ endif
+ endif
+ endif
+ endfor
+ endif
+endfunction
+
+" Close related windows if target window is not visible.
+function! coc#float#check_related() abort
+ let invalids = []
+ let ids = coc#float#get_float_win_list(1)
+ for id in ids
+ let target = getwinvar(id, 'target_winid', 0)
+ if (target && index(ids, target) == -1) || getwinvar(id, 'kind', '') == 'pum'
+ call add(invalids, id)
+ endif
+ endfor
+ if !s:popup_list_api
+ let s:popup_list = filter(ids, "index(invalids, v:val) == -1")
+ endif
+ for id in invalids
+ call coc#float#close(id)
+ endfor
+endfunction
+
+" Dimension of window with lines relative to cursor
+" Width & height excludes border & padding
+function! coc#float#get_config_cursor(lines, config) abort
+ let preferTop = get(a:config, 'preferTop', 0)
+ let title = get(a:config, 'title', '')
+ let border = get(a:config, 'border', [0, 0, 0, 0])
+ if s:empty_border(border) && len(title)
+ let border = [1, 1, 1, 1]
+ endif
+ let bh = get(border, 0, 0) + get(border, 2, 0)
+ let vh = &lines - &cmdheight - 1
+ if vh <= 0
+ return v:null
+ endif
+ let maxWidth = coc#helper#min(get(a:config, 'maxWidth', &columns - 1), &columns - 1)
+ if maxWidth < 3
+ return v:null
+ endif
+ let maxHeight = coc#helper#min(get(a:config, 'maxHeight', vh), vh)
+ let ch = 0
+ let width = coc#helper#min(40, strdisplaywidth(title)) + 3
+ for line in a:lines
+ let dw = max([1, strdisplaywidth(line)])
+ let width = max([width, dw + 2])
+ let ch += float2nr(ceil(str2float(string(dw))/(maxWidth - 2)))
+ endfor
+ let width = coc#helper#min(maxWidth, width)
+ let [lineIdx, colIdx] = coc#cursor#screen_pos()
+ " How much we should move left
+ let offsetX = coc#helper#min(get(a:config, 'offsetX', 0), colIdx)
+ let showTop = 0
+ let hb = vh - lineIdx -1
+ if lineIdx > bh + 2 && (preferTop || (lineIdx > hb && hb < ch + bh))
+ let showTop = 1
+ endif
+ let height = coc#helper#min(maxHeight, ch + bh, showTop ? lineIdx - 1 : hb)
+ if height <= bh
+ return v:null
+ endif
+ let col = - max([offsetX, colIdx - (&columns - 1 - width)])
+ let row = showTop ? - height + bh : 1
+ return {
+ \ 'row': row,
+ \ 'col': col,
+ \ 'width': width - 2,
+ \ 'height': height - bh
+ \ }
+endfunction
+
+function! coc#float#create_pum_float(winid, bufnr, lines, config) abort
+ if !pumvisible() || !s:float_supported
+ return v:null
+ endif
+ let pumbounding = a:config['pumbounding']
+ let pw = pumbounding['width'] + get(pumbounding, 'scrollbar', 0)
+ let rp = &columns - pumbounding['col'] - pw
+ let showRight = pumbounding['col'] > rp ? 0 : 1
+ let maxWidth = showRight ? coc#helper#min(rp - 1, a:config['maxWidth']) : coc#helper#min(pumbounding['col'] - 1, a:config['maxWidth'])
+ let border = get(a:config, 'border', [])
+ let bh = get(border, 0 ,0) + get(border, 2, 0)
+ let maxHeight = &lines - pumbounding['row'] - &cmdheight - 1 - bh
+ if maxWidth <= 2 || maxHeight < 1
+ return v:null
+ endif
+ let ch = 0
+ let width = 0
+ for line in a:lines
+ let dw = max([1, strdisplaywidth(line)])
+ let width = max([width, dw + 2])
+ let ch += float2nr(ceil(str2float(string(dw))/(maxWidth - 2)))
+ endfor
+ let width = float2nr(coc#helper#min(maxWidth, width))
+ let height = float2nr(coc#helper#min(maxHeight, ch))
+ let lines = map(a:lines, {_, s -> s =~# '^─' ? repeat('─', width - 2 + (s:is_vim && ch > height ? -1 : 0)) : s})
+ let opts = {
+ \ 'lines': lines,
+ \ 'relative': 'editor',
+ \ 'col': showRight ? pumbounding['col'] + pw : pumbounding['col'] - width - 1,
+ \ 'row': pumbounding['row'],
+ \ 'height': height,
+ \ 'width': width - 2 + (s:is_vim && ch > height ? -1 : 0),
+ \ 'codes': get(a:config, 'codes', []),
+ \ }
+ for key in ['border', 'highlight', 'borderhighlight', 'winblend', 'focusable', 'shadow']
+ if has_key(a:config, key)
+ let opts[key] = a:config[key]
+ endif
+ endfor
+ call coc#float#close_auto_hide_wins(a:winid)
+ let res = coc#float#create_float_win(a:winid, a:bufnr, opts)
+ if empty(res)
+ return v:null
+ endif
+ call setwinvar(res[0], 'kind', 'pum')
+ if has('nvim')
+ call coc#float#nvim_scrollbar(res[0])
+ endif
+ return res
+endfunction
+
+function! s:empty_border(border) abort
+ if empty(a:border)
+ return 1
+ endif
+ if a:border[0] == 0 && a:border[1] == 0 && a:border[2] == 0 && a:border[3] == 0
+ return 1
+ endif
+ return 0
+endfunction
+
+" Show float window/popup for user confirm.
+function! coc#float#prompt_confirm(title, cb) abort
+ if s:is_vim && exists('*popup_dialog')
+ try
+ call popup_dialog(a:title. ' (y/n)?', {
+ \ 'highlight': 'Normal',
+ \ 'filter': 'popup_filter_yesno',
+ \ 'callback': {id, res -> a:cb(v:null, res)},
+ \ 'borderchars': s:borderchars,
+ \ 'borderhighlight': ['MoreMsg']
+ \ })
+ catch /.*/
+ call a:cb(v:exception)
+ endtry
+ return
+ endif
+ if has('nvim-0.4.0')
+ let text = ' '. a:title . ' (y/n)? '
+ let maxWidth = coc#helper#min(78, &columns - 2)
+ let width = coc#helper#min(maxWidth, strdisplaywidth(text))
+ let maxHeight = &lines - &cmdheight - 1
+ let height = coc#helper#min(maxHeight, float2nr(ceil(str2float(string(strdisplaywidth(text)))/width)))
+ call coc#float#close_auto_hide_wins()
+ let arr = coc#float#create_float_win(0, s:prompt_win_bufnr, {
+ \ 'col': &columns/2 - width/2 - 1,
+ \ 'row': maxHeight/2 - height/2 - 1,
+ \ 'width': width,
+ \ 'height': height,
+ \ 'border': [1,1,1,1],
+ \ 'focusable': v:false,
+ \ 'relative': 'editor',
+ \ 'highlight': 'Normal',
+ \ 'borderhighlight': ['MoreMsg'],
+ \ 'style': 'minimal',
+ \ 'lines': [text],
+ \ })
+ if empty(arr)
+ call a:cb('Window create failed!')
+ return
+ endif
+ let winid = arr[0]
+ let s:prompt_win_bufnr = arr[1]
+ let res = 0
+ redraw
+ " same result as vim
+ while 1
+ let key = nr2char(getchar())
+ if key == "\"
+ let res = -1
+ break
+ elseif key == "\" || key == 'n' || key == 'N'
+ let res = 0
+ break
+ elseif key == 'y' || key == 'Y'
+ let res = 1
+ break
+ endif
+ endw
+ call coc#float#close(winid)
+ call a:cb(v:null, res)
+ " use relative editor since neovim doesn't support center position
+ elseif exists('*confirm')
+ let choice = confirm(a:title, "&Yes\n&No")
+ call a:cb(v:null, choice == 1)
+ else
+ echohl MoreMsg
+ echom a:title.' (y/n)'
+ echohl None
+ let confirm = nr2char(getchar())
+ redraw!
+ if !(confirm ==? "y" || confirm ==? "\r")
+ echohl Moremsg | echo 'Cancelled.' | echohl None
+ return 0
+ call a:cb(v:null, 0)
+ end
+ call a:cb(v:null, 1)
+ endif
+endfunction
+
+" Create buttons popup on vim
+function! coc#float#vim_buttons(winid, config) abort
+ if !has('patch-8.2.0750')
+ return
+ endif
+ let related = getwinvar(a:winid, 'related', [])
+ let winid = coc#float#get_related(a:winid, 'buttons')
+ let btns = get(a:config, 'buttons', [])
+ if empty(btns)
+ if winid
+ call s:close_win(winid)
+ " fix padding
+ let opts = popup_getoptions(a:winid)
+ let padding = get(opts, 'padding', v:null)
+ if !empty(padding)
+ let padding[2] = padding[2] - 2
+ endif
+ call popup_setoptions(a:winid, {'padding': padding})
+ endif
+ return
+ endif
+ let border = get(a:config, 'border', v:null)
+ if !winid
+ " adjusting popup padding
+ let opts = popup_getoptions(a:winid)
+ let padding = get(opts, 'padding', v:null)
+ if type(padding) == 7
+ let padding = [0, 0, 2, 0]
+ elseif len(padding) == 0
+ let padding = [1, 1, 3, 1]
+ else
+ let padding[2] = padding[2] + 2
+ endif
+ call popup_setoptions(a:winid, {'padding': padding})
+ endif
+ let borderhighlight = get(get(a:config, 'borderhighlight', []), 0, '')
+ let pos = popup_getpos(a:winid)
+ let bw = empty(border) ? 0 : get(border, 1, 0) + get(border, 3, 0)
+ let borderbottom = empty(border) ? 0 : get(border, 2, 0)
+ let borderleft = empty(border) ? 0 : get(border, 3, 0)
+ let width = pos['width'] - bw + get(pos, 'scrollbar', 0)
+ let bufnr = s:create_btns_buffer(winid ? winbufnr(winid): 0,width, btns, borderbottom)
+ let height = 2 + (borderbottom ? 1 : 0)
+ let keys = s:gen_filter_keys(getbufline(bufnr, 2)[0])
+ let options = {
+ \ 'filter': {id, key -> coc#float#vim_filter(id, key, keys[1])},
+ \ 'highlight': get(opts, 'highlight', 'CocFloating')
+ \ }
+ let config = {
+ \ 'line': pos['line'] + pos['height'] - height,
+ \ 'col': pos['col'] + borderleft,
+ \ 'minwidth': width,
+ \ 'minheight': height,
+ \ 'maxwidth': width,
+ \ 'maxheight': height,
+ \ }
+ if winid != 0
+ call popup_move(winid, config)
+ call popup_setoptions(winid, options)
+ call win_execute(winid, 'call clearmatches()')
+ else
+ let options = extend({
+ \ 'filtermode': 'nvi',
+ \ 'padding': [0, 0, 0, 0],
+ \ 'fixed': 1,
+ \ 'zindex': 99,
+ \ }, options)
+ call extend(options, config)
+ let winid = popup_create(bufnr, options)
+ if !s:popup_list_api
+ call add(s:popup_list, winid)
+ endif
+ endif
+ if winid != 0
+ if !empty(borderhighlight)
+ call coc#highlight#add_highlight(bufnr, -1, borderhighlight, 0, 0, -1)
+ call coc#highlight#add_highlight(bufnr, -1, borderhighlight, 2, 0, -1)
+ call win_execute(winid, 'call matchadd("'.borderhighlight.'", "'.s:borderchars[1].'")')
+ endif
+ call setwinvar(winid, 'kind', 'buttons')
+ call setwinvar(winid, 'target_winid', a:winid)
+ call add(related, winid)
+ call setwinvar(a:winid, 'related', related)
+ call matchaddpos('MoreMsg', map(keys[0], "[2,v:val]"), 99, -1, {'window': winid})
+ endif
+endfunction
+
+function! coc#float#nvim_float_click() abort
+ let kind = getwinvar(win_getid(), 'kind', '')
+ if kind == 'buttons'
+ if line('.') != 2
+ return
+ endif
+ let vw = strdisplaywidth(strpart(getline('.'), 0, col('.') - 1))
+ let vcols = getbufvar(bufnr('%'), 'vcols', [])
+ if index(vcols, vw) >= 0
+ return
+ endif
+ let idx = 0
+ if !empty(vcols)
+ let filtered = filter(vcols, 'v:val < vw')
+ let idx = idx + len(filtered)
+ endif
+ let winid = win_getid()
+ let target = getwinvar(winid, 'target_winid', 0)
+ if target
+ call coc#rpc#notify('FloatBtnClick', [winbufnr(target), idx])
+ call coc#float#close(target)
+ endif
+ elseif kind == 'close'
+ let target = getwinvar(win_getid(), 'target_winid', 0)
+ call coc#float#close(target)
+ endif
+endfunction
+
+" Add mapping if necessary
+function! coc#float#nvim_win_enter(winid) abort
+ let kind = getwinvar(a:winid, 'kind', '')
+ if kind == 'buttons' || kind == 'close'
+ if empty(maparg('', 'n'))
+ nnoremap :call coc#float#nvim_float_click()
+ endif
+ endif
+endfunction
+
+function! coc#float#vim_filter(winid, key, keys) abort
+ let key = tolower(a:key)
+ let idx = index(a:keys, key)
+ let target = getwinvar(a:winid, 'target_winid', 0)
+ if target && idx >= 0
+ call coc#rpc#notify('FloatBtnClick', [winbufnr(target), idx])
+ call coc#float#close(target)
+ return 1
+ endif
+ return 0
+endfunction
+
+" Create dialog at center
+function! coc#float#create_dialog(lines, config) abort
+ " dialog always have borders
+ let title = get(a:config, 'title', '')
+ let buttons = get(a:config, 'buttons', [])
+ let highlight = get(a:config, 'highlight', 'CocFloating')
+ let borderhighlight = get(a:config, 'borderhighlight', [highlight])
+ let maxheight = coc#helper#min(get(a:config, 'maxHeight', 78), &lines - &cmdheight - 6)
+ let maxwidth = coc#helper#min(get(a:config, 'maxWidth', 78), &columns - 2)
+ let close = get(a:config, 'close', 1)
+ let minwidth = s:min_btns_width(buttons)
+ if maxheight <= 0 || maxwidth <= 0 || minwidth > maxwidth
+ throw 'Not enough spaces for dialog'
+ endif
+ let ch = 0
+ let width = coc#helper#min(strdisplaywidth(title) + 1, maxwidth)
+ for line in a:lines
+ let dw = max([1, strdisplaywidth(line)])
+ if dw < maxwidth && dw > width
+ let width = dw
+ elseif dw > maxwidth
+ let width = maxwidth
+ endif
+ let ch += float2nr(ceil(str2float(string(dw))/maxwidth))
+ endfor
+ let width = max([minwidth, width])
+ let height = coc#helper#min(ch ,maxheight)
+ let opts = {
+ \ 'relative': 'editor',
+ \ 'col': &columns/2 - (width + 2)/2,
+ \ 'row': &lines/2 - (height + 4)/2,
+ \ 'width': width,
+ \ 'height': height,
+ \ 'border': [1,1,1,1],
+ \ 'title': title,
+ \ 'close': close,
+ \ 'highlight': highlight,
+ \ 'buttons': buttons,
+ \ 'borderhighlight': borderhighlight,
+ \ }
+ if get(a:config, 'cursorline', 0)
+ let opts['cursorline'] = 1
+ endif
+ let bufnr = coc#float#create_buf(0, a:lines)
+ call coc#float#close_auto_hide_wins()
+ let res = coc#float#create_float_win(0, bufnr, opts)
+ if empty(res)
+ return
+ endif
+ if has('nvim')
+ if get(a:config, 'cursorline', 0)
+ execute 'sign place 6 line=1 name=CocCurrentLine buffer='.bufnr
+ endif
+ redraw
+ call coc#float#nvim_scrollbar(res[0])
+ endif
+ return res
+endfunction
+
+function! coc#float#get_related(winid, kind) abort
+ for winid in getwinvar(a:winid, 'related', [])
+ if getwinvar(winid, 'kind', '') ==# a:kind
+ return winid
+ endif
+ endfor
+ return 0
+endfunction
+
+" Create temporarily buffer with optional lines and &bufhidden
+function! coc#float#create_buf(bufnr, ...) abort
+ if a:bufnr > 0 && bufloaded(a:bufnr)
+ let bufnr = a:bufnr
+ else
+ if s:is_vim
+ noa let bufnr = bufadd('')
+ noa call bufload(bufnr)
+ call setbufvar(bufnr, '&buflisted', 0)
+ else
+ noa let bufnr = nvim_create_buf(v:false, v:true)
+ endif
+ let bufhidden = get(a:, 2, 'wipe')
+ call setbufvar(bufnr, '&buftype', 'nofile')
+ call setbufvar(bufnr, '&bufhidden', bufhidden)
+ call setbufvar(bufnr, '&swapfile', 0)
+ call setbufvar(bufnr, '&undolevels', -1)
+ " neovim's bug
+ call setbufvar(bufnr, '&modifiable', 1)
+ endif
+ let lines = get(a:, 1, v:null)
+ if type(lines) != 7
+ if has('nvim')
+ call nvim_buf_set_lines(bufnr, 0, -1, v:false, lines)
+ else
+ silent call deletebufline(bufnr, 1, '$')
+ silent call setbufline(bufnr, 1, lines)
+ endif
+ endif
+ return bufnr
+endfunction
+
+function! coc#float#create_menu(lines, config) abort
+ let highlight = get(a:config, 'highlight', 'CocFloating')
+ let borderhighlight = get(a:config, 'borderhighlight', [highlight])
+ let opts = {
+ \ 'lines': a:lines,
+ \ 'highlight': highlight,
+ \ 'title': get(a:config, 'title', ''),
+ \ 'borderhighlight': borderhighlight,
+ \ 'maxWidth': get(a:config, 'maxWidth', 80),
+ \ 'maxHeight': get(a:config, 'maxHeight', 80),
+ \ 'border': [1, 1, 1, 1],
+ \ 'relative': 'cursor',
+ \ }
+ if s:is_vim
+ let opts['cursorline'] = 1
+ endif
+ let dimension = coc#float#get_config_cursor(a:lines, opts)
+ call extend(opts, dimension)
+ call coc#float#close_auto_hide_wins()
+ let res = coc#float#create_float_win(0, s:prompt_win_bufnr, opts)
+ if empty(res)
+ return
+ endif
+ let s:prompt_win_bufnr = res[1]
+ redraw
+ if has('nvim')
+ call coc#float#nvim_scrollbar(res[0])
+ execute 'sign unplace 6 buffer='.s:prompt_win_bufnr
+ execute 'sign place 6 line=1 name=CocCurrentLine buffer='.s:prompt_win_bufnr
+ endif
+ return res
+endfunction
+
+" Notification always have border
+" config including:
+" - title: optional title.
+" - close: default to 1
+" - borderhighlight: highlight group string
+" - timeout: timeout in miniseconds
+" - buttons: array of button text for create buttons at bottom.
+" - top: default to 1
+" - right: default to 1
+" - maxHeight: default to 10
+" - maxWidth: default to 60
+" - highlight: highlight of window, default to 'CocFloating'
+function! coc#float#create_notification(lines, config) abort
+ let close = get(a:config, 'close', 1)
+ let timeout = get(a:config, 'timeout', 0)
+ let borderhighlight = get(a:config, 'borderhighlight', 'CocFloating')
+ let highlight = get(a:config, 'highlight', 'CocFloating')
+ let title = get(a:config, 'title', '')
+ let top = get(a:config, 'top', 1)
+ let right = get(a:config, 'right', 1)
+ let buttons = get(a:config, 'buttons', [])
+ let maxHeight = get(a:config, 'maxHeight', 10)
+ let maxWidth = min([&columns - right - 10, get(a:config, 'maxWidth', 60)])
+ let progress = get(a:config, 'progress', 0)
+ let minWidth = get(a:config, 'minWidth', 1)
+ let minWidth = max([minWidth, s:min_btns_width(buttons)])
+ if &columns < right + 10 || minWidth > maxWidth
+ throw 'no enough spaces for notification'
+ endif
+ let width = min([maxWidth, max(map(a:lines + [title + ' '], "strdisplaywidth(v:val)"))])
+ let width = max([minWidth, width])
+ let height = 0
+ for line in a:lines
+ let w = max([1, strdisplaywidth(line)])
+ let height += float2nr(ceil(str2float(string(w))/width))
+ endfor
+ let height = min([maxHeight, height, &lines - &cmdheight - 1])
+ let col = &columns - right - width - 2
+ let opts = {
+ \ 'row': top,
+ \ 'col': col,
+ \ 'lines': a:lines,
+ \ 'relative': 'editor',
+ \ 'width': width,
+ \ 'height': height,
+ \ 'highlight': highlight,
+ \ 'borderhighlight': [borderhighlight],
+ \ 'border': [1, 1, 1, 1],
+ \ 'title': title,
+ \ 'close': close,
+ \ 'buttons': buttons,
+ \ }
+ call coc#float#reflow(top + height + 2 + (empty(buttons) ? 0 : 2))
+ let res = coc#float#create_float_win(0, 0, opts)
+ if empty(res)
+ return
+ endif
+ let [winid, bufnr] = res
+ call setwinvar(winid, 'kind', 'notification')
+ redraw
+ if has('nvim')
+ call coc#float#nvim_scrollbar(winid)
+ endif
+ if timeout
+ call timer_start(timeout, { -> coc#float#close(winid)})
+ endif
+ if progress
+ let start = reltime()
+ let timer = timer_start(16, { -> s:update_progress(bufnr, width, reltimefloat(reltime(start)))}, {
+ \ 'repeat': -1
+ \ })
+ call setwinvar(winid, 'timer', timer)
+ endif
+ return res
+endfunction
+
+" adjust position for notification windows
+function! coc#float#reflow(top) abort
+ let winids = coc#float#get_float_win_list()
+ let optlist = []
+ for winid in winids
+ if getwinvar(winid, 'kind', '') !=# 'notification'
+ continue
+ endif
+ call add(optlist, s:get_win_opts(winid))
+ endfor
+ call sort(optlist, {a, b -> a['row'] - b['row']})
+ "echo optlist
+ let top = a:top
+ for opts in optlist
+ if opts['row'] <= top
+ let changed = top + 1 - opts['row']
+ let opts['row'] = top + 1
+ call s:adjust_win_row(opts['winid'], changed)
+ endif
+ " adjust top
+ let top = opts['row'] + opts['height']
+ endfor
+endfunction
+
+" float/popup relative to current cursor position
+function! coc#float#cursor_relative(winid) abort
+ if !coc#float#valid(a:winid)
+ return v:null
+ endif
+ let winid = win_getid()
+ if winid == a:winid
+ return v:null
+ endif
+ let [cursorLine, cursorCol] = coc#cursor#screen_pos()
+ if has('nvim')
+ let [row, col] = nvim_win_get_position(a:winid)
+ return {'row' : row - cursorLine, 'col' : col - cursorCol}
+ endif
+ let pos = popup_getpos(a:winid)
+ return {'row' : pos['line'] - cursorLine - 1, 'col' : pos['col'] - cursorCol - 1}
+endfunction
+
+" Change border window & close window when scrollbar is shown.
+function! coc#float#nvim_scroll_adjust(winid) abort
+ let winid = coc#float#get_related(a:winid, 'border')
+ if !winid
+ return
+ endif
+ let bufnr = winbufnr(winid)
+ let lines = nvim_buf_get_lines(bufnr, 0, -1, 0)
+ if len(lines) > 2 && coc#helper#last_character(lines[1]) ==# s:borderchars[1]
+ let cw = nvim_win_get_width(a:winid)
+ let width = nvim_win_get_width(winid)
+ if width - cw != 1 + (strcharpart(lines[1], 0, 1) ==# s:borderchars[3] ? 1 : 0)
+ return
+ endif
+ call nvim_win_set_width(winid, width + 1)
+ let lastline = len(lines) - 1
+ for i in range(0, lastline)
+ let line = lines[i]
+ if i == 0 && strcharpart(lines[0], 0, 1) ==# s:borderchars[4]
+ let add = s:borderchars[0]
+ elseif i == lastline && strcharpart(lines[i], 0, 1) ==# s:borderchars[7]
+ let add = s:borderchars[2]
+ else
+ let add = ' '
+ endif
+ let prev = strcharpart(line, 0, strchars(line) - 1)
+ let lines[i] = prev . add . coc#helper#last_character(line)
+ endfor
+ call nvim_buf_set_lines(bufnr, 0, -1, 0, lines)
+ let id = coc#float#get_related(a:winid, 'close')
+ if id
+ let [row, col] = nvim_win_get_position(id)
+ call nvim_win_set_config(id, {
+ \ 'relative': 'editor',
+ \ 'row': row,
+ \ 'col': col + 1,
+ \ })
+ endif
+ endif
+endfunction
+
+" move winid include relative windows.
+function! s:adjust_win_row(winid, changed) abort
+ let ids = getwinvar(a:winid, 'related', [])
+ if s:is_vim
+ let pos = popup_getpos(a:winid)
+ if pos['line'] - 1 + a:changed + pos['height'] > &lines - &cmdheight
+ call coc#float#close(a:winid)
+ return
+ endif
+ call popup_move(a:winid, {
+ \ 'line': pos['line'] + a:changed
+ \ })
+ for winid in ids
+ let winpos = popup_getpos(winid)
+ call popup_move(winid, {
+ \ 'line': winpos['line'] + a:changed
+ \ })
+ endfor
+ else
+ let ids = [a:winid] + ids
+ " close it if it's fully shown
+ let borderwin = coc#float#get_related(a:winid, 'border')
+ let winid = borderwin == 0 ? a:winid : borderwin
+ let height = nvim_win_get_height(winid)
+ let pos = nvim_win_get_position(winid)
+ if pos[0] + a:changed + height > &lines - &cmdheight
+ call coc#float#close(a:winid)
+ return
+ endif
+ for winid in ids
+ let [row, col] = nvim_win_get_position(winid)
+ call nvim_win_set_config(winid, {
+ \ 'relative': 'editor',
+ \ 'row': row + a:changed,
+ \ 'col': col,
+ \ })
+ endfor
+ endif
+endfunction
+
+" winid, width, height, row, col (0 based).
+" works on vim & neovim, check relative window
+function! s:get_win_opts(winid) abort
+ if s:is_vim
+ let pos = popup_getpos(a:winid)
+ return {
+ \ 'winid': a:winid,
+ \ 'row': pos['line'] - 1,
+ \ 'col': pos['col'] - 1,
+ \ 'width': pos['width'],
+ \ 'height': pos['height'],
+ \ }
+ else
+ let borderwin = coc#float#get_related(a:winid, 'border')
+ let winid = borderwin == 0 ? a:winid : borderwin
+ let [row, col] = nvim_win_get_position(winid)
+ return {
+ \ 'winid': a:winid,
+ \ 'row': row,
+ \ 'col': col,
+ \ 'width': nvim_win_get_width(winid),
+ \ 'height': nvim_win_get_height(winid)
+ \ }
+ endif
+endfunction
+
+function! s:create_btns_buffer(bufnr, width, buttons, borderbottom) abort
+ let n = len(a:buttons)
+ let spaces = a:width - n + 1
+ let tw = 0
+ for txt in a:buttons
+ let tw += strdisplaywidth(txt)
+ endfor
+ if spaces < tw
+ throw 'window is too small for buttons.'
+ endif
+ let ds = (spaces - tw)/n
+ let dl = ds/2
+ let dr = ds%2 == 0 ? ds/2 : ds/2 + 1
+ let btnline = ''
+ let idxes = []
+ for idx in range(0, n - 1)
+ let txt = toupper(a:buttons[idx][0]).a:buttons[idx][1:]
+ let btnline .= repeat(' ', dl).txt.repeat(' ', dr)
+ if idx != n - 1
+ call add(idxes, strdisplaywidth(btnline))
+ let btnline .= s:borderchars[1]
+ endif
+ endfor
+ let lines = [repeat(s:borderchars[0], a:width), btnline]
+ if a:borderbottom
+ call add(lines, repeat(s:borderchars[0], a:width))
+ endif
+ for idx in idxes
+ let lines[0] = strcharpart(lines[0], 0, idx).s:borderjoinchars[0].strcharpart(lines[0], idx + 1)
+ if a:borderbottom
+ let lines[2] = strcharpart(lines[0], 0, idx).s:borderjoinchars[2].strcharpart(lines[0], idx + 1)
+ endif
+ endfor
+ let bufnr = coc#float#create_buf(a:bufnr, lines)
+ call setbufvar(bufnr, 'vcols', idxes)
+ return bufnr
+endfunction
+
+function! s:gen_filter_keys(line) abort
+ let cols = []
+ let used = []
+ let next = 1
+ for idx in range(0, strchars(a:line) - 1)
+ let ch = strcharpart(a:line, idx, 1)
+ let nr = char2nr(ch)
+ if next
+ if (nr >= 65 && nr <= 90) || (nr >= 97 && nr <= 122)
+ let lc = tolower(ch)
+ if index(used, lc) < 0 && empty(maparg(lc, 'n'))
+ let col = len(strcharpart(a:line, 0, idx)) + 1
+ call add(used, lc)
+ call add(cols, col)
+ let next = 0
+ endif
+ endif
+ else
+ if ch == s:borderchars[1]
+ let next = 1
+ endif
+ endif
+ endfor
+ return [cols, used]
+endfunction
+
+function! s:close_win(winid) abort
+ if a:winid <= 0
+ return
+ endif
+ " vim not throw for none exists winid
+ if s:is_vim
+ call popup_close(a:winid)
+ else
+ if nvim_win_is_valid(a:winid)
+ call nvim_win_close(a:winid, 1)
+ endif
+ endif
+endfunction
+
+function! s:nvim_create_keymap(winid) abort
+ if a:winid == 0
+ return
+ endif
+ if exists('*nvim_buf_set_keymap')
+ let bufnr = winbufnr(a:winid)
+ call nvim_buf_set_keymap(bufnr, 'n', '', ':call coc#float#nvim_float_click()', {
+ \ 'silent': v:true,
+ \ 'nowait': v:true
+ \ })
+ else
+ let curr = win_getid()
+ let m = mode()
+ if m == 'n' || m == 'i' || m == 'ic'
+ noa call win_gotoid(a:winid)
+ nnoremap :call coc#float#nvim_float_click()
+ noa call win_gotoid(curr)
+ endif
+ endif
+endfunction
+
+" getwininfo is buggy on neovim, use topline, width & height should for content
+function! s:nvim_get_botline(topline, height, width, bufnr) abort
+ let lines = getbufline(a:bufnr, a:topline, a:topline + a:height - 1)
+ let botline = a:topline
+ let count = 0
+ for i in range(0, len(lines) - 1)
+ let w = coc#helper#max(1, strdisplaywidth(lines[i]))
+ let lh = float2nr(ceil(str2float(string(w))/a:width))
+ let count = count + lh
+ let botline = a:topline + i
+ if count >= a:height
+ break
+ endif
+ endfor
+ return botline
+endfunction
+
+" get popup position for vim8 based on config of neovim float window
+function! s:popup_position(config) abort
+ let relative = get(a:config, 'relative', 'editor')
+ if relative ==# 'cursor'
+ return [s:popup_cursor(a:config['row']), s:popup_cursor(a:config['col'])]
+ endif
+ return [a:config['row'] + 1, a:config['col'] + 1]
+endfunction
+
+function! s:add_related(winid, target) abort
+ let arr = getwinvar(a:target, 'related', [])
+ if index(arr, a:winid) >= 0
+ return
+ endif
+ call add(arr, a:winid)
+ call setwinvar(a:target, 'related', arr)
+endfunction
+
+function! s:popup_cursor(n) abort
+ if a:n == 0
+ return 'cursor'
+ endif
+ if a:n < 0
+ return 'cursor'.a:n
+ endif
+ return 'cursor+'.a:n
+endfunction
+
+function! s:is_blocking() abort
+ if coc#prompt#activated()
+ return 1
+ endif
+ return 0
+endfunction
+
+" max firstline of lines, height > 0, width > 0
+function! s:max_firstline(lines, height, width) abort
+ let max = len(a:lines)
+ let remain = a:height
+ for line in reverse(copy(a:lines))
+ let w = max([1, strdisplaywidth(line)])
+ let dh = float2nr(ceil(str2float(string(w))/a:width))
+ if remain - dh < 0
+ break
+ endif
+ let remain = remain - dh
+ let max = max - 1
+ endfor
+ return min([len(a:lines), max + 1])
+endfunction
+
+" Get best lnum by topline
+function! s:get_cursorline(topline, lines, scrolloff, width, height) abort
+ let lastline = len(a:lines)
+ if a:topline == lastline
+ return lastline
+ endif
+ let bottomline = a:topline
+ let used = 0
+ for lnum in range(a:topline, lastline)
+ let w = max([1, strdisplaywidth(a:lines[lnum - 1])])
+ let dh = float2nr(ceil(str2float(string(w))/a:width))
+ if used + dh >= a:height || lnum == lastline
+ let bottomline = lnum
+ break
+ endif
+ let used += dh
+ endfor
+ let cursorline = a:topline + a:scrolloff
+ if cursorline + a:scrolloff > bottomline
+ " unable to satisfy scrolloff
+ let cursorline = (a:topline + bottomline)/2
+ endif
+ return cursorline
+endfunction
+
+" Get firstline for full scroll
+function! s:get_topline(topline, lines, forward, height, width) abort
+ let used = 0
+ let lnums = a:forward ? range(a:topline, len(a:lines)) : reverse(range(1, a:topline))
+ let topline = a:forward ? len(a:lines) : 1
+ for lnum in lnums
+ let w = max([1, strdisplaywidth(a:lines[lnum - 1])])
+ let dh = float2nr(ceil(str2float(string(w))/a:width))
+ if used + dh >= a:height
+ let topline = lnum
+ break
+ endif
+ let used += dh
+ endfor
+ if topline == a:topline
+ if a:forward
+ let topline = min([len(a:lines), topline + 1])
+ else
+ let topline = max([1, topline - 1])
+ endif
+ endif
+ return topline
+endfunction
+
+" topline content_height content_width
+function! s:get_options(winid) abort
+ if has('nvim')
+ let width = nvim_win_get_width(a:winid)
+ if getwinvar(a:winid, '&foldcolumn', 0)
+ let width = width - 1
+ endif
+ let info = getwininfo(a:winid)[0]
+ return {
+ \ 'topline': info['topline'],
+ \ 'height': nvim_win_get_height(a:winid),
+ \ 'width': width
+ \ }
+ else
+ let pos = popup_getpos(a:winid)
+ return {
+ \ 'topline': pos['firstline'],
+ \ 'width': pos['core_width'],
+ \ 'height': pos['core_height']
+ \ }
+ endif
+endfunction
+
+function! s:win_setview(winid, topline, lnum) abort
+ if has('nvim')
+ call coc#compat#execute(a:winid, 'call winrestview({"lnum":'.a:lnum.',"topline":'.a:topline.'})')
+ call timer_start(10, { -> coc#float#nvim_refresh_scrollbar(a:winid) })
+ else
+ call coc#compat#execute(a:winid, 'exe '.a:lnum)
+ call popup_setoptions(a:winid, {
+ \ 'firstline': a:topline,
+ \ })
+ endif
+endfunction
+
+function! s:min_btns_width(buttons) abort
+ if empty(a:buttons)
+ return 0
+ endif
+ let minwidth = len(a:buttons)*3 - 1
+ for txt in a:buttons
+ let minwidth = minwidth + strdisplaywidth(txt)
+ endfor
+ return minwidth
+endfunction
+
+function! s:update_progress(bufnr, width, ts) abort
+ let duration = 5000
+ " count of blocks
+ let width = float2nr((a:width + 0.0)/4)
+ let percent = (float2nr(a:ts*1000)%duration + 0.0)/duration
+ let line = repeat(s:progresschars[0], a:width)
+ let startIdx = float2nr(round(a:width * percent))
+ let endIdx = startIdx + width
+ let delta = a:width - endIdx
+ if delta > 0
+ let line = s:str_compose(line, startIdx, repeat(s:progresschars[1], width))
+ else
+ let inserted = repeat(s:progresschars[1], width + delta)
+ let line = s:str_compose(line, startIdx, inserted)
+ let line = s:str_compose(line, 0, repeat(s:progresschars[1], - delta))
+ endif
+ call setbufline(a:bufnr, 1, line)
+endfunction
+
+function! s:str_compose(line, idx, text) abort
+ let first = strcharpart(a:line, 0, a:idx)
+ return first.a:text.strcharpart(a:line, a:idx + strwidth(a:text))
+endfunction
+
+function! s:add_highlights(winid, config, create) abort
+ let codes = get(a:config, 'codes', [])
+ let highlights = get(a:config, 'highlights', [])
+ if empty(codes) && empty(highlights) && a:create
+ return
+ endif
+ let bgGroup = get(a:config, 'highlight', 'CocFloating')
+ for obj in codes
+ let hlGroup = get(obj, 'hlGroup', v:null)
+ if !empty(hlGroup)
+ let obj['hlGroup'] = coc#highlight#compose_hlgroup(hlGroup, bgGroup)
+ endif
+ endfor
+ call coc#highlight#add_highlights(a:winid, codes, highlights)
+endfunction
diff --git a/private_dot_config/nvim/plugged/coc.nvim/autoload/coc/helper.vim b/private_dot_config/nvim/plugged/coc.nvim/autoload/coc/helper.vim
new file mode 100644
index 0000000..8bdc9b8
--- /dev/null
+++ b/private_dot_config/nvim/plugged/coc.nvim/autoload/coc/helper.vim
@@ -0,0 +1,148 @@
+scriptencoding utf-8
+" Helper methods for viml
+
+function! coc#helper#get_charactor(line, col) abort
+ return strchars(strpart(a:line, 0, a:col - 1))
+endfunction
+
+function! coc#helper#last_character(line) abort
+ return strcharpart(a:line, strchars(a:line) - 1, 1)
+endfunction
+
+function! coc#helper#obj_equal(one, two) abort
+ for key in keys(a:one)
+ if a:one[key] != a:two[key]
+ return 0
+ endif
+ endfor
+ return 1
+endfunction
+
+" get change between two lines
+function! coc#helper#str_diff(curr, previous, col) abort
+ let end = strpart(a:curr, a:col - 1)
+ let start = strpart(a:curr, 0, a:col -1)
+ let endOffset = 0
+ let startOffset = 0
+ let currLen = strchars(a:curr)
+ let prevLen = strchars(a:previous)
+ if len(end)
+ let endLen = strchars(end)
+ for i in range(min([prevLen, endLen]))
+ if strcharpart(end, endLen - 1 - i, 1) ==# strcharpart(a:previous, prevLen -1 -i, 1)
+ let endOffset = endOffset + 1
+ else
+ break
+ endif
+ endfor
+ endif
+ let remain = endOffset == 0 ? a:previous : strcharpart(a:previous, 0, prevLen - endOffset)
+ if len(remain)
+ for i in range(min([strchars(remain), strchars(start)]))
+ if strcharpart(remain, i, 1) ==# strcharpart(start, i ,1)
+ let startOffset = startOffset + 1
+ else
+ break
+ endif
+ endfor
+ endif
+ return {
+ \ 'start': startOffset,
+ \ 'end': prevLen - endOffset,
+ \ 'text': strcharpart(a:curr, startOffset, currLen - startOffset - endOffset)
+ \ }
+endfunction
+
+function! coc#helper#str_apply(content, diff) abort
+ let totalLen = strchars(a:content)
+ let endLen = totalLen - a:diff['end']
+ return strcharpart(a:content, 0, a:diff['start']).a:diff['text'].strcharpart(a:content, a:diff['end'], endLen)
+endfunction
+
+" insert inserted to line at position, use ... when result is too long
+" line should only contains character has strwidth equals 1
+function! coc#helper#str_compose(line, position, inserted) abort
+ let width = strwidth(a:line)
+ let text = a:inserted
+ let res = a:line
+ let need_truncate = a:position + strwidth(text) + 1 > width
+ if need_truncate
+ let remain = width - a:position - 3
+ if remain < 2
+ " use text for full line, use first & end of a:line, ignore position
+ let res = strcharpart(a:line, 0, 1)
+ let w = strwidth(res)
+ for i in range(strchars(text))
+ let c = strcharpart(text, i, 1)
+ let a = strwidth(c)
+ if w + a <= width - 1
+ let w = w + a
+ let res = res.c
+ endif
+ endfor
+ let res = res.strcharpart(a:line, w)
+ else
+ let res = strcharpart(a:line, 0, a:position)
+ let w = strwidth(res)
+ for i in range(strchars(text))
+ let c = strcharpart(text, i, 1)
+ let a = strwidth(c)
+ if w + a <= width - 3
+ let w = w + a
+ let res = res.c
+ endif
+ endfor
+ let res = res.'..'
+ let w = w + 2
+ let res = res.strcharpart(a:line, w)
+ endif
+ else
+ let first = strcharpart(a:line, 0, a:position)
+ let res = first.text.strcharpart(a:line, a:position + strwidth(text))
+ endif
+ return res
+endfunction
+
+" Return new dict with keys removed
+function! coc#helper#dict_omit(dict, keys) abort
+ let res = {}
+ for key in keys(a:dict)
+ if index(a:keys, key) == -1
+ let res[key] = a:dict[key]
+ endif
+ endfor
+ return res
+endfunction
+
+" Return new dict with keys only
+function! coc#helper#dict_pick(dict, keys) abort
+ let res = {}
+ for key in keys(a:dict)
+ if index(a:keys, key) != -1
+ let res[key] = a:dict[key]
+ endif
+ endfor
+ return res
+endfunction
+
+" support for float values
+function! coc#helper#min(first, ...) abort
+ let val = a:first
+ for i in range(0, len(a:000) - 1)
+ if a:000[i] < val
+ let val = a:000[i]
+ endif
+ endfor
+ return val
+endfunction
+
+" support for float values
+function! coc#helper#max(first, ...) abort
+ let val = a:first
+ for i in range(0, len(a:000) - 1)
+ if a:000[i] > val
+ let val = a:000[i]
+ endif
+ endfor
+ return val
+endfunction
diff --git a/private_dot_config/nvim/plugged/coc.nvim/autoload/coc/highlight.vim b/private_dot_config/nvim/plugged/coc.nvim/autoload/coc/highlight.vim
new file mode 100644
index 0000000..1d77c56
--- /dev/null
+++ b/private_dot_config/nvim/plugged/coc.nvim/autoload/coc/highlight.vim
@@ -0,0 +1,523 @@
+scriptencoding utf-8
+let s:is_vim = !has('nvim')
+let s:clear_match_by_window = has('nvim-0.5.0') || has('patch-8.1.1084')
+let s:prop_offset = get(g:, 'coc_text_prop_offset', 1000)
+let s:namespace_map = {}
+let s:ns_id = 1
+
+if has('nvim-0.5.0')
+ try
+ call getmatches(0)
+ catch /^Vim\%((\a\+)\)\=:E118/
+ let s:clear_match_by_window = 0
+ endtry
+endif
+
+" Get namespaced coc highlights from range of bufnr
+" start - 0 based start line index
+" end - 0 based end line index, could be -1 for last line (exclusive)
+function! coc#highlight#get(bufnr, key, start, end) abort
+ if !has('nvim-0.5.0') && !exists('*prop_list')
+ throw 'Get highlights requires neovim 0.5.0 or vim support prop_list()'
+ endif
+ if !has_key(s:namespace_map, a:key) || !bufloaded(a:bufnr)
+ return {}
+ endif
+ let ns = coc#highlight#create_namespace(a:key)
+ let current = {}
+ if has('nvim-0.5.0')
+ let end = a:end == -1 ? [-1, -1] : [a:end - 1, 0]
+ let markers = nvim_buf_get_extmarks(a:bufnr, ns, [a:start, 0], end, {'details': v:true})
+ for [_, row, start_col, details] in markers
+ let delta = details['end_row'] - row
+ if delta > 1 || (delta == 1 && details['end_col'] != 0)
+ " Don't known neovim's api for multiple lines markers.
+ continue
+ endif
+ let lines = getbufline(a:bufnr, row + 1)
+ if empty(lines)
+ " It's possible that markers exceeded last line.
+ continue
+ endif
+ let text = lines[0]
+ let curr = get(current, string(row), [])
+ call add(curr, {
+ \ 'hlGroup': details['hl_group'],
+ \ 'lnum': row,
+ \ 'colStart': start_col,
+ \ 'colEnd': delta == 1 ? strlen(text) : details['end_col']
+ \ })
+ let current[string(row)] = curr
+ endfor
+ else
+ let id = s:prop_offset + ns
+ " we could only get textprops line by line
+ let end = a:end == -1 ? getbufinfo(a:bufnr)[0]['linecount'] : a:end
+ for line in range(a:start + 1, end)
+ let items = []
+ for prop in prop_list(line, {'bufnr': a:bufnr, 'id': id})
+ " vim have support for cross line text props, but we're not using
+ call add(items, {
+ \ 'hlGroup': s:prop_type_hlgroup(prop['type']),
+ \ 'lnum': line - 1,
+ \ 'colStart': prop['col'] - 1,
+ \ 'colEnd': prop['col'] - 1 + prop['length'] - (prop['end'] == 0 ? 1 : 0),
+ \ })
+ endfor
+ if !empty(items)
+ let current[string(line - 1)] = items
+ endif
+ endfor
+ endif
+ return current
+endfunction
+
+" Update highlights by check exists highlights.
+function! coc#highlight#update_highlights(bufnr, key, highlights, ...) abort
+ let bufnr = a:bufnr
+ if a:bufnr == 0
+ let bufnr = bufnr('%')
+ endif
+ if !bufloaded(bufnr)
+ return
+ endif
+ let start = get(a:, 1, 0)
+ let end = get(a:, 2, -1)
+ if empty(a:highlights)
+ call coc#highlight#clear_highlight(bufnr, a:key, start, end)
+ return
+ endif
+ let total = len(a:highlights)
+ " index list that exists with current highlights
+ let exists = []
+ let ns = coc#highlight#create_namespace(a:key)
+ let currIndex = 0
+ if has('nvim-0.5.0') || exists('*prop_list')
+ let current = coc#highlight#get(bufnr, a:key, start, end)
+ for lnum in sort(map(keys(current), 'str2nr(v:val)'), {a, b -> a - b})
+ let items = current[lnum]
+ let indexes = []
+ let nextIndex = currIndex
+ if currIndex != total
+ for item in items
+ for i in range(currIndex, total - 1)
+ let hi = a:highlights[i]
+ if hi['lnum'] > item['lnum']
+ let nextIndex = i
+ break
+ endif
+ if coc#helper#obj_equal(item, hi)
+ call add(indexes, i)
+ let nextIndex = max([nextIndex, i + 1])
+ endif
+ endfor
+ endfor
+ endif
+ let currIndex = nextIndex
+ " all highlights of current line exists, not clear.
+ if len(indexes) == len(items)
+ let exists = exists + indexes
+ else
+ if has('nvim')
+ call nvim_buf_clear_namespace(bufnr, ns, lnum, lnum + 1)
+ else
+ call coc#api#call('buf_clear_namespace', [bufnr, ns, lnum, lnum + 1])
+ endif
+ endif
+ endfor
+ if has('nvim') && end == -1
+ let count = nvim_buf_line_count(bufnr)
+ " remove highlights exceed last line.
+ call nvim_buf_clear_namespace(bufnr, ns, count, -1)
+ endif
+ else
+ call coc#highlight#clear_highlight(bufnr, a:key, start, end)
+ endif
+ let indexes = range(0, total - 1)
+ if !empty(exists)
+ let indexes = filter(indexes, 'index(exists, v:val) == -1')
+ endif
+ for i in indexes
+ let hi = a:highlights[i]
+ call coc#highlight#add_highlight(bufnr, ns, hi['hlGroup'], hi['lnum'], hi['colStart'], hi['colEnd'])
+ endfor
+endfunction
+
+function! coc#highlight#get_highlights(bufnr, key) abort
+ if !has_key(s:namespace_map, a:key) || !bufloaded(a:bufnr)
+ return []
+ endif
+ let res = []
+ let ns = s:namespace_map[a:key]
+ if exists('*prop_list')
+ let lines = getbufline(a:bufnr, 1, '$')
+ let linecount = len(lines)
+ for line in range(1, linecount)
+ for prop in prop_list(line, {'bufnr': a:bufnr, 'id': s:prop_offset + ns})
+ if prop['start'] == 0 || prop['end'] == 0
+ " multi line tokens are not supported; simply ignore it
+ continue
+ endif
+ let text = lines[line - 1]
+ call add(res, {
+ \ 'hlGroup': s:prop_type_hlgroup(prop['type']),
+ \ 'lnum': line - 1,
+ \ 'colStart': coc#helper#get_charactor(text, prop['col']),
+ \ 'colEnd': coc#helper#get_charactor(text, prop['col'] + prop['length'])
+ \ })
+ endfor
+ endfor
+ elseif has('nvim-0.5.0')
+ let markers = nvim_buf_get_extmarks(a:bufnr, ns, 0, -1, {'details': v:true})
+ let lines = getbufline(a:bufnr, 1, '$')
+ let total = len(lines)
+ for [_, line, start_col, details] in markers
+ if line >= total
+ " Could be markers exceed end of line
+ continue
+ endif
+ let text = lines[line]
+ let delta = details['end_row'] - line
+ if delta > 1 || (delta == 1 && details['end_col'] != 0)
+ " can't handle, single line only
+ continue
+ endif
+ call add(res, {
+ \ 'hlGroup': details['hl_group'],
+ \ 'lnum': line,
+ \ 'colStart': coc#helper#get_charactor(text, start_col + 1),
+ \ 'colEnd': delta == 1 ? strchars(text) : coc#helper#get_charactor(text, details['end_col'] + 1)
+ \ })
+ endfor
+ else
+ throw 'Get highlights requires neovim 0.5.0 or vim support prop_list'
+ endif
+ return res
+endfunction
+
+" highlight LSP range,
+function! coc#highlight#ranges(bufnr, key, hlGroup, ranges) abort
+ let bufnr = a:bufnr == 0 ? bufnr('%') : a:bufnr
+ if !bufloaded(bufnr) || !exists('*getbufline')
+ return
+ endif
+ let synmaxcol = getbufvar(a:bufnr, '&synmaxcol', 1000)
+ if synmaxcol == 0
+ let synmaxcol = 1000
+ endif
+ let synmaxcol = min([synmaxcol, 1000])
+ let srcId = coc#highlight#create_namespace(a:key)
+ for range in a:ranges
+ let start = range['start']
+ let end = range['end']
+ for lnum in range(start['line'] + 1, end['line'] + 1)
+ let arr = getbufline(bufnr, lnum)
+ let line = empty(arr) ? '' : arr[0]
+ if empty(line)
+ continue
+ endif
+ if start['character'] > synmaxcol || end['character'] > synmaxcol
+ continue
+ endif
+ " TODO don't know how to count UTF16 code point, should work most cases.
+ let colStart = lnum == start['line'] + 1 ? strlen(strcharpart(line, 0, start['character'])) : 0
+ let colEnd = lnum == end['line'] + 1 ? strlen(strcharpart(line, 0, end['character'])) : -1
+ if colStart == colEnd
+ continue
+ endif
+ call coc#highlight#add_highlight(bufnr, srcId, a:hlGroup, lnum - 1, colStart, colEnd)
+ endfor
+ endfor
+endfunction
+
+function! coc#highlight#add_highlight(bufnr, src_id, hl_group, line, col_start, col_end) abort
+ if has('nvim')
+ call nvim_buf_add_highlight(a:bufnr, a:src_id, a:hl_group, a:line, a:col_start, a:col_end)
+ else
+ call coc#api#call('buf_add_highlight', [a:bufnr, a:src_id, a:hl_group, a:line, a:col_start, a:col_end])
+ endif
+endfunction
+
+function! coc#highlight#clear_highlight(bufnr, key, start_line, end_line) abort
+ let bufnr = a:bufnr == 0 ? bufnr('%') : a:bufnr
+ if !bufloaded(bufnr)
+ return
+ endif
+ let src_id = coc#highlight#create_namespace(a:key)
+ if has('nvim')
+ call nvim_buf_clear_namespace(a:bufnr, src_id, a:start_line, a:end_line)
+ else
+ call coc#api#call('buf_clear_namespace', [a:bufnr, src_id, a:start_line, a:end_line])
+ endif
+endfunction
+
+" highlight buffer in winid with CodeBlock &HighlightItems
+" export interface HighlightItem {
+" lnum: number // 0 based
+" hlGroup: string
+" colStart: number // 0 based
+" colEnd: number
+" }
+" export interface CodeBlock {
+" filetype?: string
+" hlGroup?: string
+" startLine: number // 0 based
+" endLine: number
+" }
+function! coc#highlight#add_highlights(winid, codes, highlights) abort
+ " clear highlights
+ call coc#compat#execute(a:winid, 'syntax clear')
+ let bufnr = winbufnr(a:winid)
+ call coc#highlight#clear_highlight(bufnr, -1, 0, -1)
+ if !empty(a:codes)
+ call coc#highlight#highlight_lines(a:winid, a:codes)
+ endif
+ if !empty(a:highlights)
+ for item in a:highlights
+ call coc#highlight#add_highlight(bufnr, -1, item['hlGroup'], item['lnum'], item['colStart'], item['colEnd'])
+ endfor
+ endif
+endfunction
+
+
+" Add highlights to line groups of winid, support hlGroup and filetype
+" config should have startLine, endLine (0 based, end excluded) and filetype or hlGroup
+" endLine should > startLine and endLine is excluded
+"
+" export interface CodeBlock {
+" filetype?: string
+" hlGroup?: string
+" startLine: number // 0 based
+" endLine: number
+" }
+function! coc#highlight#highlight_lines(winid, blocks) abort
+ let region_id = 1
+ let defined = []
+ let cmds = []
+ for config in a:blocks
+ let start = config['startLine'] + 1
+ let end = config['endLine'] == -1 ? len(getbufline(winbufnr(a:winid), 1, '$')) + 1 : config['endLine'] + 1
+ let filetype = get(config, 'filetype', '')
+ let hlGroup = get(config, 'hlGroup', '')
+ if !empty(hlGroup)
+ call add(cmds, 'syntax region '.hlGroup.' start=/\%'.start.'l/ end=/\%'.end.'l/')
+ else
+ let filetype = matchstr(filetype, '\v^\w+')
+ if empty(filetype) || filetype == 'txt' || index(get(g:, 'coc_markdown_disabled_languages', []), filetype) != -1
+ continue
+ endif
+ if index(defined, filetype) == -1
+ call add(cmds, 'syntax include @'.toupper(filetype).' syntax/'.filetype.'.vim')
+ call add(cmds, 'unlet! b:current_syntax')
+ call add(defined, filetype)
+ endif
+ call add(cmds, 'syntax region CodeBlock'.region_id.' start=/\%'.start.'l/ end=/\%'.end.'l/ contains=@'.toupper(filetype).' keepend')
+ let region_id = region_id + 1
+ endif
+ endfor
+ if !empty(cmds)
+ call coc#compat#execute(a:winid, cmds, 'silent!')
+ endif
+endfunction
+
+" Copmpose hlGroups with foreground and background colors.
+function! coc#highlight#compose_hlgroup(fgGroup, bgGroup) abort
+ let hlGroup = 'Fg'.a:fgGroup.'Bg'.a:bgGroup
+ if a:fgGroup ==# a:bgGroup
+ return a:fgGroup
+ endif
+ if hlexists(hlGroup)
+ return hlGroup
+ endif
+ let fgId = synIDtrans(hlID(a:fgGroup))
+ let bgId = synIDtrans(hlID(a:bgGroup))
+ let guifg = synIDattr(fgId, 'reverse', 'gui') !=# '1' ? synIDattr(fgId, 'fg', 'gui') : synIDattr(fgId, 'bg', 'gui')
+ let guibg = synIDattr(bgId, 'reverse', 'gui') !=# '1' ? synIDattr(bgId, 'bg', 'gui') : synIDattr(bgId, 'fg', 'gui')
+ let ctermfg = synIDattr(fgId, 'reverse', 'cterm') !=# '1' ? synIDattr(fgId, 'fg', 'cterm') : synIDattr(fgId, 'bg', 'cterm')
+ let ctermbg = synIDattr(bgId, 'reverse', 'cterm') !=# '1' ? synIDattr(bgId, 'bg', 'cterm') : synIDattr(bgId, 'fg', 'cterm')
+ let bold = synIDattr(fgId, 'bold') ==# '1'
+ let italic = synIDattr(fgId, 'italic') ==# '1'
+ let underline = synIDattr(fgId, 'underline') ==# '1'
+ let cmd = 'silent hi ' . hlGroup
+ if !empty(guifg)
+ let cmd .= ' guifg=' . guifg
+ endif
+ if !empty(ctermfg)
+ let cmd .= ' ctermfg=' . ctermfg
+ elseif guifg =~# '^#'
+ let cmd .= ' ctermfg=' . coc#color#rgb2term(strpart(guifg, 1))
+ endif
+ if !empty(guibg)
+ let cmd .= ' guibg=' . guibg
+ endif
+ if !empty(ctermbg)
+ let cmd .= ' ctermbg=' . ctermbg
+ elseif guibg =~# '^#'
+ let cmd .= ' ctermbg=' . coc#color#rgb2term(strpart(guibg, 1))
+ endif
+ if bold
+ let cmd .= ' cterm=bold gui=bold'
+ elseif italic
+ let cmd .= ' cterm=italic gui=italic'
+ elseif underline
+ let cmd .= ' cterm=underline gui=underline'
+ endif
+ execute cmd
+ return hlGroup
+endfunction
+
+" add matches for winid, use 0 for current window.
+function! coc#highlight#match_ranges(winid, bufnr, ranges, hlGroup, priority) abort
+ let winid = a:winid == 0 ? win_getid() : a:winid
+ let bufnr = a:bufnr == 0 ? winbufnr(winid) : a:bufnr
+ if empty(getwininfo(winid)) || (a:bufnr != 0 && winbufnr(a:winid) != a:bufnr)
+ " not valid
+ return []
+ endif
+ if !s:clear_match_by_window
+ let curr = win_getid()
+ if has('nvim')
+ noa call nvim_set_current_win(winid)
+ else
+ noa call win_gotoid(winid)
+ endif
+ endif
+ let ids = []
+ for range in a:ranges
+ let pos = []
+ let start = range['start']
+ let end = range['end']
+ for lnum in range(start['line'] + 1, end['line'] + 1)
+ let arr = getbufline(bufnr, lnum)
+ let line = empty(arr) ? '' : arr[0]
+ if empty(line)
+ continue
+ endif
+ let colStart = lnum == start['line'] + 1 ? strlen(strcharpart(line, 0, start['character'])) + 1 : 1
+ let colEnd = lnum == end['line'] + 1 ? strlen(strcharpart(line, 0, end['character'])) + 1 : strlen(line) + 1
+ if colStart == colEnd
+ continue
+ endif
+ call add(pos, [lnum, colStart, colEnd - colStart])
+ endfor
+ if !empty(pos)
+ let opts = s:clear_match_by_window ? {'window': a:winid} : {}
+ let i = 1
+ let l = []
+ for p in pos
+ call add(l, p)
+ if i % 8 == 0
+ let id = matchaddpos(a:hlGroup, l, a:priority, -1, opts)
+ call add(ids, id)
+ let l = []
+ endif
+ let i += 1
+ endfor
+ if !empty(l)
+ let id = matchaddpos(a:hlGroup, l, a:priority, -1, opts)
+ call add(ids, id)
+ endif
+ endif
+ endfor
+ if !s:clear_match_by_window
+ if has('nvim')
+ noa call nvim_set_current_win(curr)
+ else
+ noa call win_gotoid(curr)
+ endif
+ endif
+ return ids
+endfunction
+
+" Clear matches by hlGroup regexp.
+function! coc#highlight#clear_match_group(winid, match) abort
+ let winid = a:winid == 0 ? win_getid() : a:winid
+ if empty(getwininfo(winid))
+ " not valid
+ return
+ endif
+ if s:clear_match_by_window
+ let arr = filter(getmatches(winid), 'v:val["group"] =~# "'.a:match.'"')
+ for item in arr
+ call matchdelete(item['id'], winid)
+ endfor
+ else
+ let curr = win_getid()
+ let switch = exists('*nvim_set_current_win') && curr != winid
+ if switch
+ noa call nvim_set_current_win(a:winid)
+ endif
+ if win_getid() == winid
+ let arr = filter(getmatches(), 'v:val["group"] =~# "'.a:match.'"')
+ for item in arr
+ call matchdelete(item['id'])
+ endfor
+ endif
+ if switch
+ noa call nvim_set_current_win(curr)
+ endif
+ endif
+endfunction
+
+" Clear matches by match ids, use 0 for current win.
+function! coc#highlight#clear_matches(winid, ids)
+ let winid = a:winid == 0 ? win_getid() : a:winid
+ if empty(getwininfo(winid))
+ " not valid
+ return
+ endif
+ if s:clear_match_by_window
+ for id in a:ids
+ try
+ call matchdelete(id, winid)
+ catch /^Vim\%((\a\+)\)\=:E803/
+ " ignore
+ endtry
+ endfor
+ else
+ let curr = win_getid()
+ let switch = exists('*nvim_set_current_win') && curr != winid
+ if switch
+ noa call nvim_set_current_win(a:winid)
+ endif
+ if win_getid() == winid
+ for id in a:ids
+ try
+ call matchdelete(id)
+ catch /^Vim\%((\a\+)\)\=:E803/
+ " ignore
+ endtry
+ endfor
+ endif
+ if switch
+ noa call nvim_set_current_win(curr)
+ endif
+ endif
+endfunction
+
+function! s:prop_type_hlgroup(type) abort
+ if a:type=~# '^CocHighlight'
+ return a:type[12:]
+ endif
+ return prop_type_get(a:type)['highlight']
+endfunction
+
+function! coc#highlight#create_namespace(key) abort
+ if type(a:key) == 0
+ return a:key
+ endif
+ if has_key(s:namespace_map, a:key)
+ return s:namespace_map[a:key]
+ endif
+ if has('nvim')
+ let s:namespace_map[a:key] = nvim_create_namespace('coc-'.a:key)
+ else
+ let s:namespace_map[a:key] = s:ns_id
+ let s:ns_id = s:ns_id + 1
+ endif
+ return s:namespace_map[a:key]
+endfunction
+
+function! coc#highlight#get_syntax_name(lnum, col)
+ return synIDattr(synIDtrans(synID(a:lnum,a:col,1)),"name")
+endfunction
diff --git a/private_dot_config/nvim/plugged/coc.nvim/autoload/coc/list.vim b/private_dot_config/nvim/plugged/coc.nvim/autoload/coc/list.vim
new file mode 100644
index 0000000..21f2bb3
--- /dev/null
+++ b/private_dot_config/nvim/plugged/coc.nvim/autoload/coc/list.vim
@@ -0,0 +1,314 @@
+scriptencoding utf-8
+let s:is_vim = !has('nvim')
+let s:prefix = '[List Preview]'
+" filetype detect could be slow.
+let s:filetype_map = {
+ \ 'vim': 'vim',
+ \ 'ts': 'typescript',
+ \ 'js': 'javascript',
+ \ 'html': 'html',
+ \ 'css': 'css'
+ \ }
+
+function! coc#list#getchar() abort
+ return coc#prompt#getchar()
+endfunction
+
+function! coc#list#setlines(bufnr, lines, append)
+ if a:append
+ silent call appendbufline(a:bufnr, '$', a:lines)
+ else
+ if exists('*deletebufline')
+ silent call deletebufline(a:bufnr, len(a:lines) + 1, '$')
+ else
+ let n = len(a:lines) + 1
+ let saved_reg = @"
+ silent execute n.',$d'
+ let @" = saved_reg
+ endif
+ silent call setbufline(a:bufnr, 1, a:lines)
+ endif
+endfunction
+
+function! coc#list#options(...)
+ let list = ['--top', '--tab', '--normal', '--no-sort', '--input', '--strict',
+ \ '--regex', '--interactive', '--number-select', '--auto-preview',
+ \ '--ignore-case', '--no-quit', '--first']
+ if get(g:, 'coc_enabled', 0)
+ let names = coc#rpc#request('listNames', [])
+ call extend(list, names)
+ endif
+ return join(list, "\n")
+endfunction
+
+function! coc#list#names(...) abort
+ let names = coc#rpc#request('listNames', [])
+ return join(names, "\n")
+endfunction
+
+function! coc#list#status(name)
+ if !exists('b:list_status') | return '' | endif
+ return get(b:list_status, a:name, '')
+endfunction
+
+function! coc#list#create(position, height, name, numberSelect)
+ if a:position ==# 'tab'
+ execute 'silent tabe list:///'.a:name
+ else
+ execute 'silent keepalt '.(a:position ==# 'top' ? '' : 'botright').a:height.'sp list:///'.a:name
+ execute 'resize '.a:height
+ endif
+ if a:numberSelect
+ setl norelativenumber
+ setl number
+ else
+ setl nonumber
+ setl norelativenumber
+ setl signcolumn=yes
+ endif
+ return [bufnr('%'), win_getid()]
+endfunction
+
+" close list windows
+function! coc#list#clean_up() abort
+ for i in range(1, winnr('$'))
+ let bufname = bufname(winbufnr(i))
+ if bufname =~# 'list://'
+ execute i.'close!'
+ endif
+ endfor
+endfunction
+
+function! coc#list#setup(source)
+ let b:list_status = {}
+ setl buftype=nofile nobuflisted nofen nowrap
+ setl norelativenumber bufhidden=wipe cursorline winfixheight
+ setl tabstop=1 nolist nocursorcolumn undolevels=-1
+ setl signcolumn=auto
+ if has('nvim-0.5.0') || has('patch-8.1.0864')
+ setl scrolloff=0
+ endif
+ if exists('&cursorlineopt')
+ setl cursorlineopt=both
+ endif
+ setl filetype=list
+ syntax case ignore
+ let source = a:source[8:]
+ let name = toupper(source[0]).source[1:]
+ execute 'syntax match Coc'.name.'Line /\v^.*$/'
+ nnoremap c
+endfunction
+
+" Check if previewwindow exists on current tab.
+function! coc#list#has_preview()
+ for i in range(1, winnr('$'))
+ let preview = getwinvar(i, 'previewwindow', getwinvar(i, '&previewwindow', 0))
+ if preview
+ return i
+ endif
+ endfor
+ return 0
+endfunction
+
+" Get previewwindow from tabnr, use 0 for current tab
+function! coc#list#get_preview(...) abort
+ let tabnr = get(a:, 1, 0) == 0 ? tabpagenr() : a:1
+ let info = gettabinfo(tabnr)
+ if !empty(info)
+ for win in info[0]['windows']
+ if getwinvar(win, 'previewwindow', 0)
+ return win
+ endif
+ endfor
+ endif
+ return -1
+endfunction
+
+function! coc#list#scroll_preview(dir) abort
+ let winnr = coc#list#has_preview()
+ if !winnr
+ return
+ endif
+ let winid = win_getid(winnr)
+ if exists('*win_execute')
+ call win_execute(winid, "normal! ".(a:dir ==# 'up' ? "\" : "\"))
+ else
+ let id = win_getid()
+ noa call win_gotoid(winid)
+ execute "normal! ".(a:dir ==# 'up' ? "\" : "\")
+ noa call win_gotoid(id)
+ endif
+endfunction
+
+function! coc#list#restore(winid, height)
+ if has('nvim') && nvim_win_is_valid(a:winid)
+ call nvim_win_set_height(a:winid, a:height)
+ elseif s:is_vim && exists('*win_execute')
+ call win_execute(a:winid, 'noa resize '.a:height, 'silent!')
+ redraw
+ endif
+endfunction
+
+function! coc#list#set_height(height) abort
+ if winnr('$') == 1| return | endif
+ execute 'resize '.a:height
+endfunction
+
+function! coc#list#hide(original, height, winid) abort
+ let arr = win_id2tabwin(a:winid)
+ " close preview window
+ if !empty(arr) && arr[0] != 0
+ silent! pclose!
+ let previewwin = coc#list#get_preview(arr[0])
+ call coc#window#close(previewwin)
+ endif
+ if !empty(getwininfo(a:original))
+ call win_gotoid(a:original)
+ endif
+ if a:winid
+ silent! call coc#window#close(a:winid)
+ endif
+ if !empty(a:height) && win_getid() == a:original
+ if exists('*nvim_win_set_height')
+ call nvim_win_set_height(a:original, a:height)
+ elseif win_getid() == a:original
+ execute 'resize '.a:height
+ endif
+ endif
+endfunction
+
+" Improve preview performance by reused window & buffer.
+" lines - list of lines
+" config.position - could be 'below' 'top' 'tab'.
+" config.winid - id of original window.
+" config.name - (optional )name of preview buffer.
+" config.splitRight - (optional) split to right when 1.
+" config.lnum - (optional) current line number
+" config.filetype - (optional) filetype of lines.
+" config.hlGroup - (optional) highlight group.
+" config.maxHeight - (optional) max height of window, valid for 'below' & 'top' position.
+function! coc#list#preview(lines, config) abort
+ if s:is_vim && !exists('*win_execute')
+ throw 'win_execute function required for preview, please upgrade your vim.'
+ return
+ endif
+ let name = fnamemodify(get(a:config, 'name', ''), ':.')
+ let lines = a:lines
+ if empty(lines)
+ if get(a:config, 'scheme', 'file') != 'file'
+ let bufnr = s:load_buffer(name)
+ if bufnr != 0
+ let lines = getbufline(bufnr, 1, '$')
+ else
+ let lines = ['']
+ endif
+ else
+ " Show empty lines so not close window.
+ let lines = ['']
+ endif
+ endif
+ let winid = coc#list#get_preview(0)
+ let bufnr = winid == -1 ? 0 : winbufnr(winid)
+ " Try reuse buffer & window
+ let bufnr = coc#float#create_buf(bufnr, lines)
+ if bufnr == 0
+ return
+ endif
+ call setbufvar(bufnr, '&synmaxcol', 500)
+ let filetype = get(a:config, 'filetype', '')
+ let extname = matchstr(name, '\.\zs[^.]\+$')
+ if empty(filetype) && !empty(extname)
+ let filetype = get(s:filetype_map, extname, '')
+ endif
+ let range = get(a:config, 'range', v:null)
+ let hlGroup = get(a:config, 'hlGroup', 'Search')
+ let lnum = get(a:config, 'lnum', 1)
+ let position = get(a:config, 'position', 'below')
+ let original = get(a:config, 'winid', -1)
+ if winid == -1
+ let change = position != 'tab' && get(a:config, 'splitRight', 0)
+ let curr = win_getid()
+ if change
+ if original && win_id2win(original)
+ noa call win_gotoid(original)
+ else
+ noa wincmd t
+ endif
+ execute 'noa belowright vert sb '.bufnr
+ let winid = win_getid()
+ elseif position == 'tab' || get(a:config, 'splitRight', 0)
+ execute 'noa belowright vert sb '.bufnr
+ let winid = win_getid()
+ else
+ let mod = position == 'top' ? 'below' : 'above'
+ let height = s:get_height(lines, a:config)
+ execute 'noa '.mod.' sb +resize\ '.height.' '.bufnr
+ let winid = win_getid()
+ endif
+ noa call winrestview({"lnum": lnum ,"topline":max([1, lnum - 3])})
+ call setwinvar(winid, '&signcolumn', 'no')
+ call setwinvar(winid, '&number', 1)
+ call setwinvar(winid, '&cursorline', 0)
+ call setwinvar(winid, '&relativenumber', 0)
+ call setwinvar(winid, 'previewwindow', 1)
+ noa call win_gotoid(curr)
+ else
+ let height = s:get_height(lines, a:config)
+ if height > 0
+ if s:is_vim
+ let curr = win_getid()
+ noa call win_gotoid(winid)
+ execute 'silent! noa resize '.height
+ noa call win_gotoid(curr)
+ else
+ call nvim_win_set_height(winid, height)
+ endif
+ endif
+ call coc#compat#execute(winid, ['syntax clear', 'noa call winrestview({"lnum":'.lnum.',"topline":'.max([1, lnum - 3]).'})'])
+ endif
+ call setwinvar(winid, '&foldenable', 0)
+ if s:prefix.' '.name != bufname(bufnr)
+ if s:is_vim
+ call win_execute(winid, 'noa file '.fnameescape(s:prefix.' '.name), 'silent!')
+ else
+ silent! noa call nvim_buf_set_name(bufnr, s:prefix.' '.name)
+ endif
+ endif
+ " highlights
+ if !empty(filetype)
+ let start = max([0, lnum - 300])
+ let end = min([len(lines), lnum + 300])
+ call coc#highlight#highlight_lines(winid, [{'filetype': filetype, 'startLine': start, 'endLine': end}])
+ call coc#compat#execute(winid, 'syn sync fromstart')
+ else
+ call coc#compat#execute(winid, 'filetype detect')
+ let ft = getbufvar(bufnr, '&filetype', '')
+ if !empty(extname) && !empty(ft)
+ let s:filetype_map[extname] = ft
+ endif
+ endif
+ call sign_unplace('coc', {'buffer': bufnr})
+ call coc#compat#execute(winid, 'call clearmatches()')
+ if !empty(range)
+ call sign_place(1, 'coc', 'CocCurrentLine', bufnr, {'lnum': lnum})
+ call coc#highlight#match_ranges(winid, bufnr, [range], hlGroup, 10)
+ endif
+ redraw
+endfunction
+
+function! s:get_height(lines, config) abort
+ if get(a:config, 'splitRight', 0) || get(a:config, 'position', 'below') == 'tab'
+ return 0
+ endif
+ let height = min([get(a:config, 'maxHeight', 10), len(a:lines), &lines - &cmdheight - 2])
+ return height
+endfunction
+
+function! s:load_buffer(name) abort
+ if exists('*bufadd') && exists('*bufload')
+ let bufnr = bufadd(a:name)
+ call bufload(bufnr)
+ return bufnr
+ endif
+ return 0
+endfunction
diff --git a/private_dot_config/nvim/plugged/coc.nvim/autoload/coc/prompt.vim b/private_dot_config/nvim/plugged/coc.nvim/autoload/coc/prompt.vim
new file mode 100644
index 0000000..cbe4a97
--- /dev/null
+++ b/private_dot_config/nvim/plugged/coc.nvim/autoload/coc/prompt.vim
@@ -0,0 +1,210 @@
+scriptencoding utf-8
+let s:is_vim = !has('nvim')
+let s:activated = 0
+let s:session_names = []
+let s:saved_ve = &t_ve
+let s:saved_cursor = &guicursor
+let s:gui = has('gui_running') || has('nvim')
+
+let s:char_map = {
+ \ "\": '',
+ \ "\": '',
+ \ "\": '',
+ \ "\": '',
+ \ "\": '',
+ \ "\": '',
+ \ "\": '',
+ \ "\": '',
+ \ "\": '',
+ \ "\": '',
+ \ "\": '',
+ \ "\": '',
+ \ "\":'' ,
+ \ "\":'' ,
+ \ "\