added
This commit is contained in:
commit
a7aa42621c
|
@ -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
|
|
@ -0,0 +1,2 @@
|
|||
#!/bin/zsh
|
||||
[ -f "$HOME/.config/zsh/env" ] && source "$HOME/.config/zsh/env"
|
|
@ -0,0 +1,2 @@
|
|||
[General]
|
||||
theme=Monochrome
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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-
|
||||
|
|
@ -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
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh
|
||||
if [ -n "$FIFO_UEBERZUG" ]; then
|
||||
printf '{"action": "remove", "identifier": "PREVIEW"}\n' > "$FIFO_UEBERZUG"
|
||||
fi
|
|
@ -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
|
|
@ -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
|
|
@ -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 <BS> 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='⚡'
|
|
@ -0,0 +1,7 @@
|
|||
Copyright 2018-2018 by Qiming Zhao <chemzqm@gmail.com>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.
|
|
@ -0,0 +1,334 @@
|
|||
<p align="center">
|
||||
<a href="https://www.vim.org/scripts/script.php?script_id=5779">
|
||||
<img alt="Coc Logo" src="https://user-images.githubusercontent.com/251450/55009068-f4ed2780-501c-11e9-9a3b-cf3aa6ab9272.png" height="160" />
|
||||
</a>
|
||||
<p align="center">Make your Vim/Neovim as smart as VSCode.</p>
|
||||
<p align="center">
|
||||
<a href="LICENSE.md"><img alt="Software License" src="https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square"></a>
|
||||
<a href="https://github.com/neoclide/coc.nvim/actions"><img alt="Actions" src="https://img.shields.io/github/workflow/status/neoclide/coc.nvim/coc.nvim%20CI?style=flat-square"></a>
|
||||
<a href="https://codecov.io/gh/neoclide/coc.nvim"><img alt="Codecov Coverage Status" src="https://img.shields.io/codecov/c/github/neoclide/coc.nvim.svg?style=flat-square"></a>
|
||||
<a href="doc/coc.txt"><img alt="Doc" src="https://img.shields.io/badge/doc-%3Ah%20coc.txt-brightgreen.svg?style=flat-square"></a>
|
||||
<a href="https://gitter.im/neoclide/coc.nvim"><img alt="Gitter" src="https://img.shields.io/gitter/room/neoclide/coc.nvim.svg?style=flat-square"></a>
|
||||
</p>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
<img alt="Gif" src="https://user-images.githubusercontent.com/251450/55285193-400a9000-53b9-11e9-8cff-ffe4983c5947.gif" width="60%" />
|
||||
|
||||
_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 <tab>` 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 <tab>' to make sure tab is not mapped by
|
||||
" other plugin before putting this into your config.
|
||||
inoremap <silent><expr> <TAB>
|
||||
\ pumvisible() ? "\<C-n>" :
|
||||
\ <SID>check_back_space() ? "\<TAB>" :
|
||||
\ coc#refresh()
|
||||
inoremap <expr><S-TAB> pumvisible() ? "\<C-p>" : "\<C-h>"
|
||||
|
||||
function! s:check_back_space() abort
|
||||
let col = col('.') - 1
|
||||
return !col || getline('.')[col - 1] =~# '\s'
|
||||
endfunction
|
||||
|
||||
" Use <c-space> to trigger completion.
|
||||
if has('nvim')
|
||||
inoremap <silent><expr> <c-space> coc#refresh()
|
||||
else
|
||||
inoremap <silent><expr> <c-@> coc#refresh()
|
||||
endif
|
||||
|
||||
" Make <CR> auto-select the first completion item and notify coc.nvim to
|
||||
" format on enter, <cr> could be remapped by other vim plugin
|
||||
inoremap <silent><expr> <cr> pumvisible() ? coc#_select_confirm()
|
||||
\: "\<C-g>u\<CR>\<c-r>=coc#on_enter()\<CR>"
|
||||
|
||||
" Use `[g` and `]g` to navigate diagnostics
|
||||
" Use `:CocDiagnostics` to get all diagnostics of current buffer in location list.
|
||||
nmap <silent> [g <Plug>(coc-diagnostic-prev)
|
||||
nmap <silent> ]g <Plug>(coc-diagnostic-next)
|
||||
|
||||
" GoTo code navigation.
|
||||
nmap <silent> gd <Plug>(coc-definition)
|
||||
nmap <silent> gy <Plug>(coc-type-definition)
|
||||
nmap <silent> gi <Plug>(coc-implementation)
|
||||
nmap <silent> gr <Plug>(coc-references)
|
||||
|
||||
" Use K to show documentation in preview window.
|
||||
nnoremap <silent> K :call <SID>show_documentation()<CR>
|
||||
|
||||
function! s:show_documentation()
|
||||
if (index(['vim','help'], &filetype) >= 0)
|
||||
execute 'h '.expand('<cword>')
|
||||
elseif (coc#rpc#ready())
|
||||
call CocActionAsync('doHover')
|
||||
else
|
||||
execute '!' . &keywordprg . " " . expand('<cword>')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Highlight the symbol and its references when holding the cursor.
|
||||
autocmd CursorHold * silent call CocActionAsync('highlight')
|
||||
|
||||
" Symbol renaming.
|
||||
nmap <leader>rn <Plug>(coc-rename)
|
||||
|
||||
" Formatting selected code.
|
||||
xmap <leader>f <Plug>(coc-format-selected)
|
||||
nmap <leader>f <Plug>(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: `<leader>aap` for current paragraph
|
||||
xmap <leader>a <Plug>(coc-codeaction-selected)
|
||||
nmap <leader>a <Plug>(coc-codeaction-selected)
|
||||
|
||||
" Remap keys for applying codeAction to the current buffer.
|
||||
nmap <leader>ac <Plug>(coc-codeaction)
|
||||
" Apply AutoFix to problem on the current line.
|
||||
nmap <leader>qf <Plug>(coc-fix-current)
|
||||
|
||||
" Map function and class text objects
|
||||
" NOTE: Requires 'textDocument.documentSymbol' support from the language server.
|
||||
xmap if <Plug>(coc-funcobj-i)
|
||||
omap if <Plug>(coc-funcobj-i)
|
||||
xmap af <Plug>(coc-funcobj-a)
|
||||
omap af <Plug>(coc-funcobj-a)
|
||||
xmap ic <Plug>(coc-classobj-i)
|
||||
omap ic <Plug>(coc-classobj-i)
|
||||
xmap ac <Plug>(coc-classobj-a)
|
||||
omap ac <Plug>(coc-classobj-a)
|
||||
|
||||
" Remap <C-f> and <C-b> for scroll float windows/popups.
|
||||
if has('nvim-0.4.0') || has('patch-8.2.0750')
|
||||
nnoremap <silent><nowait><expr> <C-f> coc#float#has_scroll() ? coc#float#scroll(1) : "\<C-f>"
|
||||
nnoremap <silent><nowait><expr> <C-b> coc#float#has_scroll() ? coc#float#scroll(0) : "\<C-b>"
|
||||
inoremap <silent><nowait><expr> <C-f> coc#float#has_scroll() ? "\<c-r>=coc#float#scroll(1)\<cr>" : "\<Right>"
|
||||
inoremap <silent><nowait><expr> <C-b> coc#float#has_scroll() ? "\<c-r>=coc#float#scroll(0)\<cr>" : "\<Left>"
|
||||
vnoremap <silent><nowait><expr> <C-f> coc#float#has_scroll() ? coc#float#scroll(1) : "\<C-f>"
|
||||
vnoremap <silent><nowait><expr> <C-b> coc#float#has_scroll() ? coc#float#scroll(0) : "\<C-b>"
|
||||
endif
|
||||
|
||||
" Use CTRL-S for selections ranges.
|
||||
" Requires 'textDocument/selectionRange' support of language server.
|
||||
nmap <silent> <C-s> <Plug>(coc-range-select)
|
||||
xmap <silent> <C-s> <Plug>(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', <f-args>)
|
||||
|
||||
" 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 <silent><nowait> <space>a :<C-u>CocList diagnostics<cr>
|
||||
" Manage extensions.
|
||||
nnoremap <silent><nowait> <space>e :<C-u>CocList extensions<cr>
|
||||
" Show commands.
|
||||
nnoremap <silent><nowait> <space>c :<C-u>CocList commands<cr>
|
||||
" Find symbol of current document.
|
||||
nnoremap <silent><nowait> <space>o :<C-u>CocList outline<cr>
|
||||
" Search workspace symbols.
|
||||
nnoremap <silent><nowait> <space>s :<C-u>CocList -I symbols<cr>
|
||||
" Do default action for next item.
|
||||
nnoremap <silent><nowait> <space>j :<C-u>CocNext<CR>
|
||||
" Do default action for previous item.
|
||||
nnoremap <silent><nowait> <space>k :<C-u>CocPrev<CR>
|
||||
" Resume latest coc list.
|
||||
nnoremap <silent><nowait> <space>p :<C-u>CocListResume<CR>
|
||||
```
|
||||
|
||||
## 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.
|
||||
|
||||
<a href="https://opencollective.com/cocnvim/backer/0/website?requireActive=false" target="_blank"><img src="https://opencollective.com/cocnvim/backer/0/avatar.svg?requireActive=false"></a>
|
||||
<a href="https://opencollective.com/cocnvim/backer/1/website?requireActive=false" target="_blank"><img src="https://opencollective.com/cocnvim/backer/1/avatar.svg?requireActive=false"></a>
|
||||
<a href="https://opencollective.com/cocnvim/backer/2/website?requireActive=false" target="_blank"><img src="https://opencollective.com/cocnvim/backer/2/avatar.svg?requireActive=false"></a>
|
||||
<a href="https://opencollective.com/cocnvim/backer/3/website?requireActive=false" target="_blank"><img src="https://opencollective.com/cocnvim/backer/3/avatar.svg?requireActive=false"></a>
|
||||
<a href="https://opencollective.com/cocnvim/backer/4/website?requireActive=false" target="_blank"><img src="https://opencollective.com/cocnvim/backer/4/avatar.svg?requireActive=false"></a>
|
||||
<a href="https://opencollective.com/cocnvim/backer/5/website?requireActive=false" target="_blank"><img src="https://opencollective.com/cocnvim/backer/5/avatar.svg?requireActive=false"></a>
|
||||
<a href="https://opencollective.com/cocnvim/backer/6/website?requireActive=false" target="_blank"><img src="https://opencollective.com/cocnvim/backer/6/avatar.svg?requireActive=false"></a>
|
||||
<a href="https://opencollective.com/cocnvim/backer/7/website?requireActive=false" target="_blank"><img src="https://opencollective.com/cocnvim/backer/7/avatar.svg?requireActive=false"></a>
|
||||
<a href="https://opencollective.com/cocnvim/backer/8/website?requireActive=false" target="_blank"><img src="https://opencollective.com/cocnvim/backer/8/avatar.svg?requireActive=false"></a>
|
||||
<a href="https://opencollective.com/cocnvim/backer/9/website?requireActive=false" target="_blank"><img src="https://opencollective.com/cocnvim/backer/9/avatar.svg?requireActive=false"></a>
|
||||
<a href="https://opencollective.com/cocnvim/backer/10/website?requireActive=false" target="_blank"><img src="https://opencollective.com/cocnvim/backer/10/avatar.svg?requireActive=false"></a>
|
||||
<a href="https://opencollective.com/cocnvim/backer/11/website?requireActive=false" target="_blank"><img src="https://opencollective.com/cocnvim/backer/11/avatar.svg?requireActive=false"></a>
|
||||
<a href="https://opencollective.com/cocnvim/backer/12/website?requireActive=false" target="_blank"><img src="https://opencollective.com/cocnvim/backer/12/avatar.svg?requireActive=false"></a>
|
||||
<a href="https://opencollective.com/cocnvim/backer/13/website?requireActive=false" target="_blank"><img src="https://opencollective.com/cocnvim/backer/13/avatar.svg?requireActive=false"></a>
|
||||
<a href="https://opencollective.com/cocnvim/backer/14/website?requireActive=false" target="_blank"><img src="https://opencollective.com/cocnvim/backer/14/avatar.svg?requireActive=false"></a>
|
||||
<a href="https://opencollective.com/cocnvim/backer/15/website?requireActive=false" target="_blank"><img src="https://opencollective.com/cocnvim/backer/15/avatar.svg?requireActive=false"></a>
|
||||
<a href="https://opencollective.com/cocnvim/backer/16/website?requireActive=false" target="_blank"><img src="https://opencollective.com/cocnvim/backer/16/avatar.svg?requireActive=false"></a>
|
||||
<a href="https://opencollective.com/cocnvim/backer/17/website?requireActive=false" target="_blank"><img src="https://opencollective.com/cocnvim/backer/17/avatar.svg?requireActive=false"></a>
|
||||
<a href="https://opencollective.com/cocnvim/backer/18/website?requireActive=false" target="_blank"><img src="https://opencollective.com/cocnvim/backer/18/avatar.svg?requireActive=false"></a>
|
||||
<a href="https://opencollective.com/cocnvim/backer/19/website?requireActive=false" target="_blank"><img src="https://opencollective.com/cocnvim/backer/19/avatar.svg?requireActive=false"></a>
|
||||
<a href="https://opencollective.com/cocnvim/backer/20/website?requireActive=false" target="_blank"><img src="https://opencollective.com/cocnvim/backer/20/avatar.svg?requireActive=false"></a>
|
||||
<a href="https://opencollective.com/cocnvim/backer/21/website?requireActive=false" target="_blank"><img src="https://opencollective.com/cocnvim/backer/21/avatar.svg?requireActive=false"></a>
|
||||
<a href="https://opencollective.com/cocnvim/backer/22/website?requireActive=false" target="_blank"><img src="https://opencollective.com/cocnvim/backer/22/avatar.svg?requireActive=false"></a>
|
||||
<a href="https://opencollective.com/cocnvim/backer/23/website?requireActive=false" target="_blank"><img src="https://opencollective.com/cocnvim/backer/23/avatar.svg?requireActive=false"></a>
|
||||
<a href="https://opencollective.com/cocnvim/backer/24/website?requireActive=false" target="_blank"><img src="https://opencollective.com/cocnvim/backer/24/avatar.svg?requireActive=false"></a>
|
||||
<a href="https://opencollective.com/cocnvim/backer/25/website?requireActive=false" target="_blank"><img src="https://opencollective.com/cocnvim/backer/25/avatar.svg?requireActive=false"></a>
|
||||
<a href="https://opencollective.com/cocnvim/backer/26/website?requireActive=false" target="_blank"><img src="https://opencollective.com/cocnvim/backer/26/avatar.svg?requireActive=false"></a>
|
||||
<a href="https://opencollective.com/cocnvim/backer/27/website?requireActive=false" target="_blank"><img src="https://opencollective.com/cocnvim/backer/27/avatar.svg?requireActive=false"></a>
|
||||
<a href="https://opencollective.com/cocnvim/backer/28/website?requireActive=false" target="_blank"><img src="https://opencollective.com/cocnvim/backer/28/avatar.svg?requireActive=false"></a>
|
||||
<a href="https://opencollective.com/cocnvim/backer/29/website?requireActive=false" target="_blank"><img src="https://opencollective.com/cocnvim/backer/29/avatar.svg?requireActive=false"></a>
|
||||
<a href="https://opencollective.com/cocnvim/backer/30/website?requireActive=false" target="_blank"><img src="https://opencollective.com/cocnvim/backer/30/avatar.svg?requireActive=false"></a>
|
||||
<a href="https://opencollective.com/cocnvim/backer/31/website?requireActive=false" target="_blank"><img src="https://opencollective.com/cocnvim/backer/31/avatar.svg?requireActive=false"></a>
|
||||
<a href="https://opencollective.com/cocnvim/backer/32/website?requireActive=false" target="_blank"><img src="https://opencollective.com/cocnvim/backer/32/avatar.svg?requireActive=false"></a>
|
||||
<a href="https://opencollective.com/cocnvim/backer/33/website?requireActive=false" target="_blank"><img src="https://opencollective.com/cocnvim/backer/33/avatar.svg?requireActive=false"></a>
|
||||
|
||||
<a href="https://opencollective.com/cocnvim#backer" target="_blank"><img src="https://images.opencollective.com/static/images/become_backer.svg"></a>
|
||||
|
||||
## Support the project
|
||||
|
||||
Buy cloud service from [www.vultr.com](https://www.vultr.com/?ref=8890170-6G)
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
|
@ -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 "\<c-r>=coc#start()\<CR>"
|
||||
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 "\<c-r>=coc#rpc#".a:method."('doKeymap', ['".a:key."'])\<CR>"
|
||||
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 <cmd> specific key to preselect item at once
|
||||
call feedkeys("\<Cmd>\<CR>" , '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("\<Plug>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 "\<C-y>"
|
||||
elseif pumvisible()
|
||||
return "\<down>\<C-y>"
|
||||
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("\<C-e>", 'in')
|
||||
endfunction
|
||||
|
||||
function! coc#_cancel()
|
||||
" hack for close pum
|
||||
if pumvisible()
|
||||
let g:coc#_context = {'start': 0, 'preselect': -1,'candidates': []}
|
||||
call feedkeys("\<Plug>CocRefresh", 'i')
|
||||
call coc#rpc#notify('stopCompletion', [])
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#_select() abort
|
||||
if !pumvisible() | return | endif
|
||||
call feedkeys("\<C-y>", '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 <buffer> '.i.' <Cmd>call nvim_select_popupmenu_item('.(i - 1).', v:true, v:true, {})<cr>'
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! coc#_unmap()
|
||||
if !s:select_api | return | endif
|
||||
for i in range(1, 9)
|
||||
exe 'silent! iunmap <buffer> '.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
|
|
@ -0,0 +1,634 @@
|
|||
" ============================================================================
|
||||
" Description: Client api used by vim8
|
||||
" Author: Qiming Zhao <chemzqm@gmail.com>
|
||||
" 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:
|
|
@ -0,0 +1,331 @@
|
|||
scriptencoding utf-8
|
||||
let s:root = expand('<sfile>: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
|
|
@ -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
|
|
@ -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 <buffer> '.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 <buffer> '.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 .= '<buffer> '.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
|
|
@ -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
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
|
@ -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
|
|
@ -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 <silent><nowait><buffer> <esc> <C-w>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' ? "\<C-u>" : "\<C-d>"))
|
||||
else
|
||||
let id = win_getid()
|
||||
noa call win_gotoid(winid)
|
||||
execute "normal! ".(a:dir ==# 'up' ? "\<C-u>" : "\<C-d>")
|
||||
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
|
|
@ -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 = {
|
||||
\ "\<Plug>": '<plug>',
|
||||
\ "\<Esc>": '<esc>',
|
||||
\ "\<Tab>": '<tab>',
|
||||
\ "\<S-Tab>": '<s-tab>',
|
||||
\ "\<bs>": '<bs>',
|
||||
\ "\<right>": '<right>',
|
||||
\ "\<left>": '<left>',
|
||||
\ "\<up>": '<up>',
|
||||
\ "\<down>": '<down>',
|
||||
\ "\<home>": '<home>',
|
||||
\ "\<end>": '<end>',
|
||||
\ "\<cr>": '<cr>',
|
||||
\ "\<PageUp>":'<PageUp>' ,
|
||||
\ "\<PageDown>":'<PageDown>' ,
|
||||
\ "\<FocusGained>":'<FocusGained>',
|
||||
\ "\<FocusLost>":'<FocusLost>',
|
||||
\ "\<ScrollWheelUp>": '<ScrollWheelUp>',
|
||||
\ "\<ScrollWheelDown>": '<ScrollWheelDown>',
|
||||
\ "\<LeftMouse>": '<LeftMouse>',
|
||||
\ "\<LeftDrag>": '<LeftDrag>',
|
||||
\ "\<LeftRelease>": '<LeftRelease>',
|
||||
\ "\<2-LeftMouse>": '<2-LeftMouse>',
|
||||
\ "\<C-a>": '<C-a>',
|
||||
\ "\<C-b>": '<C-b>',
|
||||
\ "\<C-c>": '<C-c>',
|
||||
\ "\<C-d>": '<C-d>',
|
||||
\ "\<C-e>": '<C-e>',
|
||||
\ "\<C-f>": '<C-f>',
|
||||
\ "\<C-g>": '<C-g>',
|
||||
\ "\<C-h>": '<C-h>',
|
||||
\ "\<C-j>": '<C-j>',
|
||||
\ "\<C-k>": '<C-k>',
|
||||
\ "\<C-l>": '<C-l>',
|
||||
\ "\<C-n>": '<C-n>',
|
||||
\ "\<C-o>": '<C-o>',
|
||||
\ "\<C-p>": '<C-p>',
|
||||
\ "\<C-q>": '<C-q>',
|
||||
\ "\<C-r>": '<C-r>',
|
||||
\ "\<C-s>": '<C-s>',
|
||||
\ "\<C-t>": '<C-t>',
|
||||
\ "\<C-u>": '<C-u>',
|
||||
\ "\<C-v>": '<C-v>',
|
||||
\ "\<C-w>": '<C-w>',
|
||||
\ "\<C-x>": '<C-x>',
|
||||
\ "\<C-y>": '<C-y>',
|
||||
\ "\<C-z>": '<C-z>',
|
||||
\ "\<A-a>": '<A-a>',
|
||||
\ "\<A-b>": '<A-b>',
|
||||
\ "\<A-c>": '<A-c>',
|
||||
\ "\<A-d>": '<A-d>',
|
||||
\ "\<A-e>": '<A-e>',
|
||||
\ "\<A-f>": '<A-f>',
|
||||
\ "\<A-g>": '<A-g>',
|
||||
\ "\<A-h>": '<A-h>',
|
||||
\ "\<A-i>": '<A-i>',
|
||||
\ "\<A-j>": '<A-j>',
|
||||
\ "\<A-k>": '<A-k>',
|
||||
\ "\<A-l>": '<A-l>',
|
||||
\ "\<A-m>": '<A-m>',
|
||||
\ "\<A-n>": '<A-n>',
|
||||
\ "\<A-o>": '<A-o>',
|
||||
\ "\<A-p>": '<A-p>',
|
||||
\ "\<A-q>": '<A-q>',
|
||||
\ "\<A-r>": '<A-r>',
|
||||
\ "\<A-s>": '<A-s>',
|
||||
\ "\<A-t>": '<A-t>',
|
||||
\ "\<A-u>": '<A-u>',
|
||||
\ "\<A-v>": '<A-v>',
|
||||
\ "\<A-w>": '<A-w>',
|
||||
\ "\<A-x>": '<A-x>',
|
||||
\ "\<A-y>": '<A-y>',
|
||||
\ "\<A-z>": '<A-z>',
|
||||
\ }
|
||||
|
||||
function! coc#prompt#getc() abort
|
||||
let c = getchar()
|
||||
return type(c) == type(0) ? nr2char(c) : c
|
||||
endfunction
|
||||
|
||||
function! coc#prompt#getchar() abort
|
||||
let input = coc#prompt#getc()
|
||||
if 1 != &iminsert
|
||||
return input
|
||||
endif
|
||||
"a language keymap is activated, so input must be resolved to the mapped values.
|
||||
let partial_keymap = mapcheck(input, "l")
|
||||
while partial_keymap !=# ""
|
||||
let full_keymap = maparg(input, "l")
|
||||
if full_keymap ==# "" && len(input) >= 3 "HACK: assume there are no keymaps longer than 3.
|
||||
return input
|
||||
elseif full_keymap ==# partial_keymap
|
||||
return full_keymap
|
||||
endif
|
||||
let c = coc#prompt#getc()
|
||||
if c ==# "\<Esc>" || c ==# "\<CR>"
|
||||
"if the short sequence has a valid mapping, return that.
|
||||
if !empty(full_keymap)
|
||||
return full_keymap
|
||||
endif
|
||||
return input
|
||||
endif
|
||||
let input .= c
|
||||
let partial_keymap = mapcheck(input, "l")
|
||||
endwhile
|
||||
return input
|
||||
endfunction
|
||||
|
||||
function! coc#prompt#start_prompt(session) abort
|
||||
let s:session_names = s:filter(s:session_names, a:session)
|
||||
call add(s:session_names, a:session)
|
||||
if s:activated | return | endif
|
||||
if s:is_vim
|
||||
call s:start_prompt_vim()
|
||||
else
|
||||
call s:start_prompt()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:start_prompt_vim() abort
|
||||
call timer_start(10, {-> s:start_prompt()})
|
||||
endfunction
|
||||
|
||||
function! s:start_prompt()
|
||||
if s:activated | return | endif
|
||||
if !get(g:, 'coc_disable_transparent_cursor', 0)
|
||||
if s:gui
|
||||
if has('nvim-0.5.0') && !empty(s:saved_cursor)
|
||||
set guicursor+=a:ver1-CocCursorTransparent/lCursor
|
||||
endif
|
||||
elseif s:is_vim
|
||||
set t_ve=
|
||||
endif
|
||||
endif
|
||||
let s:activated = 1
|
||||
try
|
||||
while s:activated
|
||||
let ch = coc#prompt#getchar()
|
||||
if ch ==# "\<FocusLost>" || ch ==# "\<FocusGained>" || ch ==# "\<CursorHold>"
|
||||
continue
|
||||
else
|
||||
let curr = s:current_session()
|
||||
let mapped = get(s:char_map, ch, ch)
|
||||
if !empty(curr)
|
||||
call coc#rpc#notify('InputChar', [curr, mapped, getcharmod()])
|
||||
endif
|
||||
if mapped == '<esc>'
|
||||
let s:session_names = []
|
||||
call s:reset()
|
||||
break
|
||||
endif
|
||||
endif
|
||||
endwhile
|
||||
catch /^Vim:Interrupt$/
|
||||
let s:activated = 0
|
||||
call coc#rpc#notify('InputChar', [s:current_session(), '<esc>'])
|
||||
return
|
||||
endtry
|
||||
let s:activated = 0
|
||||
endfunction
|
||||
|
||||
function! coc#prompt#stop_prompt(session)
|
||||
let s:session_names = s:filter(s:session_names, a:session)
|
||||
if len(s:session_names)
|
||||
return
|
||||
endif
|
||||
if s:activated
|
||||
let s:activated = 0
|
||||
call s:reset()
|
||||
call feedkeys("\<esc>", 'int')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#prompt#activated() abort
|
||||
return s:activated
|
||||
endfunction
|
||||
|
||||
function! s:reset() abort
|
||||
if !get(g:, 'coc_disable_transparent_cursor',0)
|
||||
" neovim has bug with revert empty &guicursor
|
||||
if s:gui && !empty(s:saved_cursor)
|
||||
if has('nvim-0.5.0')
|
||||
set guicursor+=a:ver1-Cursor/lCursor
|
||||
let &guicursor = s:saved_cursor
|
||||
endif
|
||||
elseif s:is_vim
|
||||
let &t_ve = s:saved_ve
|
||||
endif
|
||||
endif
|
||||
echo ""
|
||||
endfunction
|
||||
|
||||
function! s:current_session() abort
|
||||
if empty(s:session_names)
|
||||
return v:null
|
||||
endif
|
||||
return s:session_names[len(s:session_names) - 1]
|
||||
endfunction
|
||||
|
||||
function! s:filter(list, id) abort
|
||||
return filter(copy(a:list), 'v:val !=# a:id')
|
||||
endfunction
|
|
@ -0,0 +1,128 @@
|
|||
scriptencoding utf-8
|
||||
let s:is_win = has("win32") || has("win64")
|
||||
let s:client = v:null
|
||||
let s:name = 'coc'
|
||||
let s:is_vim = !has('nvim')
|
||||
|
||||
function! coc#rpc#start_server()
|
||||
if get(g:, 'coc_node_env', '') ==# 'test'
|
||||
" server already started
|
||||
let s:client = coc#client#create(s:name, [])
|
||||
let s:client['running'] = 1
|
||||
let s:client['chan_id'] = get(g:, 'coc_node_channel_id', 0)
|
||||
call dictwatcheradd(g:, 'coc_node_channel_id', function('s:ChannelSet'))
|
||||
return
|
||||
endif
|
||||
if empty(s:client)
|
||||
let cmd = coc#util#job_command()
|
||||
if empty(cmd) | return | endif
|
||||
let $COC_VIMCONFIG = coc#util#get_config_home()
|
||||
let $COC_DATA_HOME = coc#util#get_data_home()
|
||||
let s:client = coc#client#create(s:name, cmd)
|
||||
endif
|
||||
if !coc#client#is_running('coc')
|
||||
call s:client['start']()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#rpc#started() abort
|
||||
return !empty(s:client)
|
||||
endfunction
|
||||
|
||||
function! coc#rpc#ready()
|
||||
if empty(s:client) || s:client['running'] == 0
|
||||
return 0
|
||||
endif
|
||||
return 1
|
||||
endfunction
|
||||
|
||||
function! s:ChannelSet(dict, key, val)
|
||||
let chan_id = get(a:val, 'new', 0)
|
||||
if empty(s:client) | return | endif
|
||||
let s:client['running'] = 1
|
||||
let s:client['chan_id'] = chan_id
|
||||
call dictwatcherdel(g:, 'coc_node_channel_id', function('s:ChannelSet'))
|
||||
endfunction
|
||||
|
||||
function! coc#rpc#kill()
|
||||
let pid = get(g:, 'coc_process_pid', 0)
|
||||
if !pid | return | endif
|
||||
if s:is_win
|
||||
call system('taskkill /PID '.pid)
|
||||
else
|
||||
call system('kill -9 '.pid)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#rpc#get_errors()
|
||||
return split(execute('messages'), "\n")
|
||||
endfunction
|
||||
|
||||
function! coc#rpc#stop()
|
||||
if empty(s:client)
|
||||
return
|
||||
endif
|
||||
try
|
||||
if s:is_vim
|
||||
call job_stop(ch_getjob(s:client['channel']), 'term')
|
||||
else
|
||||
call jobstop(s:client['chan_id'])
|
||||
endif
|
||||
catch /.*/
|
||||
" ignore
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! coc#rpc#restart()
|
||||
if empty(s:client)
|
||||
call coc#rpc#start_server()
|
||||
else
|
||||
call coc#float#close_all()
|
||||
call coc#rpc#request('detach', [])
|
||||
sleep 100m
|
||||
let s:client['command'] = coc#util#job_command()
|
||||
call coc#client#restart(s:name)
|
||||
echohl MoreMsg | echom 'starting coc.nvim service' | echohl None
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#rpc#request(method, args) abort
|
||||
if !coc#rpc#ready()
|
||||
return ''
|
||||
endif
|
||||
return s:client['request'](a:method, a:args)
|
||||
endfunction
|
||||
|
||||
function! coc#rpc#notify(method, args) abort
|
||||
if !coc#rpc#ready()
|
||||
return ''
|
||||
endif
|
||||
call s:client['notify'](a:method, a:args)
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function! coc#rpc#request_async(method, args, cb) abort
|
||||
if !coc#rpc#ready()
|
||||
return cb('coc.nvim service not started.')
|
||||
endif
|
||||
call s:client['request_async'](a:method, a:args, a:cb)
|
||||
endfunction
|
||||
|
||||
" receive async response
|
||||
function! coc#rpc#async_response(id, resp, isErr) abort
|
||||
if empty(s:client)
|
||||
return
|
||||
endif
|
||||
call coc#client#on_response(s:name, a:id, a:resp, a:isErr)
|
||||
endfunction
|
||||
|
||||
" send async response to server
|
||||
function! coc#rpc#async_request(id, method, args)
|
||||
let l:Cb = {err, ... -> coc#rpc#notify('nvim_async_response_event', [a:id, err, get(a:000, 0, v:null)])}
|
||||
let args = a:args + [l:Cb]
|
||||
try
|
||||
call call(a:method, args)
|
||||
catch /.*/
|
||||
call coc#rpc#notify('nvim_async_response_event', [a:id, v:exception, v:null])
|
||||
endtry
|
||||
endfunction
|
|
@ -0,0 +1,69 @@
|
|||
scriptencoding utf-8
|
||||
let s:is_vim = !has('nvim')
|
||||
let s:map_next = 1
|
||||
|
||||
function! coc#snippet#_select_mappings()
|
||||
if !get(g:, 'coc_selectmode_mapping', 1)
|
||||
return
|
||||
endif
|
||||
|
||||
redir => mappings
|
||||
silent! smap
|
||||
redir END
|
||||
|
||||
for map in map(filter(split(mappings, '\n'),
|
||||
\ "v:val !~# '^s' && v:val !~# '^\\a*\\s*<\\S\\+>'"),
|
||||
\ "matchstr(v:val, '^\\a*\\s*\\zs\\S\\+')")
|
||||
silent! execute 'sunmap' map
|
||||
silent! execute 'sunmap <buffer>' map
|
||||
endfor
|
||||
|
||||
" same behaviour of ultisnips
|
||||
snoremap <silent> <BS> <c-g>c
|
||||
snoremap <silent> <DEL> <c-g>c
|
||||
snoremap <silent> <c-h> <c-g>c
|
||||
snoremap <c-r> <c-g>"_c<c-r>
|
||||
endfunction
|
||||
|
||||
function! coc#snippet#show_choices(lnum, col, len, values) abort
|
||||
let m = mode()
|
||||
call cursor(a:lnum, a:col + a:len)
|
||||
if m !=# 'i' | startinsert | endif
|
||||
call timer_start(20, { -> coc#_do_complete(a:col - 1, a:values, 0)})
|
||||
redraw
|
||||
endfunction
|
||||
|
||||
function! coc#snippet#enable()
|
||||
if get(b:, 'coc_snippet_active', 0) == 1
|
||||
return
|
||||
endif
|
||||
let b:coc_snippet_active = 1
|
||||
silent! unlet g:coc_selected_text
|
||||
call coc#snippet#_select_mappings()
|
||||
let nextkey = get(g:, 'coc_snippet_next', '<C-j>')
|
||||
let prevkey = get(g:, 'coc_snippet_prev', '<C-k>')
|
||||
if maparg(nextkey, 'i') =~# 'expand-jump'
|
||||
let s:map_next = 0
|
||||
endif
|
||||
if s:map_next
|
||||
execute 'inoremap <buffer><nowait><silent>'.nextkey." <C-R>=coc#rpc#request('snippetNext', [])<cr>"
|
||||
endif
|
||||
execute 'inoremap <buffer><nowait><silent>'.prevkey." <C-R>=coc#rpc#request('snippetPrev', [])<cr>"
|
||||
execute 'snoremap <buffer><nowait><silent>'.prevkey." <Esc>:call coc#rpc#request('snippetPrev', [])<cr>"
|
||||
execute 'snoremap <buffer><nowait><silent>'.nextkey." <Esc>:call coc#rpc#request('snippetNext', [])<cr>"
|
||||
endfunction
|
||||
|
||||
function! coc#snippet#disable()
|
||||
if get(b:, 'coc_snippet_active', 0) == 0
|
||||
return
|
||||
endif
|
||||
let b:coc_snippet_active = 0
|
||||
let nextkey = get(g:, 'coc_snippet_next', '<C-j>')
|
||||
let prevkey = get(g:, 'coc_snippet_prev', '<C-k>')
|
||||
if s:map_next
|
||||
silent! execute 'iunmap <buffer> <silent> '.nextkey
|
||||
endif
|
||||
silent! execute 'iunmap <buffer> <silent> '.prevkey
|
||||
silent! execute 'sunmap <buffer> <silent> '.prevkey
|
||||
silent! execute 'sunmap <buffer> <silent> '.nextkey
|
||||
endfunction
|
|
@ -0,0 +1,179 @@
|
|||
" ============================================================================
|
||||
" Description: Manage long running tasks.
|
||||
" Author: Qiming Zhao <chemzqm@gmail.com>
|
||||
" Licence: MIT licence
|
||||
" Version: 0.1
|
||||
" Last Modified: Dec 12, 2020
|
||||
" ============================================================================
|
||||
scriptencoding utf-8
|
||||
|
||||
let s:is_vim = !has('nvim')
|
||||
let s:running_task = {}
|
||||
" neovim emit strings that part of lines.
|
||||
let s:out_remain_text = {}
|
||||
let s:err_remain_text = {}
|
||||
|
||||
function! coc#task#start(id, opts)
|
||||
if coc#task#running(a:id)
|
||||
call coc#task#stop(a:id)
|
||||
endif
|
||||
let cmd = [a:opts['cmd']] + get(a:opts, 'args', [])
|
||||
let cwd = get(a:opts, 'cwd', getcwd())
|
||||
let env = get(a:opts, 'env', {})
|
||||
" cmd args cwd pty
|
||||
if s:is_vim
|
||||
let options = {
|
||||
\ 'cwd': cwd,
|
||||
\ 'err_mode': 'nl',
|
||||
\ 'out_mode': 'nl',
|
||||
\ 'err_cb': {channel, message -> s:on_stderr(a:id, [message])},
|
||||
\ 'out_cb': {channel, message -> s:on_stdout(a:id, [message])},
|
||||
\ 'exit_cb': {channel, code -> s:on_exit(a:id, code)},
|
||||
\ 'env': env,
|
||||
\}
|
||||
if has("patch-8.1.350")
|
||||
let options['noblock'] = 1
|
||||
endif
|
||||
if get(a:opts, 'pty', 0)
|
||||
let options['pty'] = 1
|
||||
endif
|
||||
let job = job_start(cmd, options)
|
||||
let status = job_status(job)
|
||||
if status !=# 'run'
|
||||
echohl Error | echom 'Failed to start '.a:id.' task' | echohl None
|
||||
return v:false
|
||||
endif
|
||||
let s:running_task[a:id] = job
|
||||
else
|
||||
let options = {
|
||||
\ 'cwd': cwd,
|
||||
\ 'on_stderr': {channel, msgs -> s:on_stderr(a:id, msgs)},
|
||||
\ 'on_stdout': {channel, msgs -> s:on_stdout(a:id, msgs)},
|
||||
\ 'on_exit': {channel, code -> s:on_exit(a:id, code)},
|
||||
\ 'detach': get(a:opts, 'detach', 0),
|
||||
\}
|
||||
let original = {}
|
||||
if !empty(env)
|
||||
if has('nvim-0.5.0')
|
||||
let options['env'] = env
|
||||
elseif exists('*setenv') && exists('*getenv')
|
||||
for key in keys(env)
|
||||
let original[key] = getenv(key)
|
||||
call setenv(key, env[key])
|
||||
endfor
|
||||
endif
|
||||
endif
|
||||
if get(a:opts, 'pty', 0)
|
||||
let options['pty'] = 1
|
||||
endif
|
||||
let chan_id = jobstart(cmd, options)
|
||||
if !empty(original)
|
||||
for key in keys(original)
|
||||
call setenv(key, original[key])
|
||||
endfor
|
||||
endif
|
||||
if chan_id <= 0
|
||||
echohl Error | echom 'Failed to start '.a:id.' task' | echohl None
|
||||
return v:false
|
||||
endif
|
||||
let s:running_task[a:id] = chan_id
|
||||
endif
|
||||
return v:true
|
||||
endfunction
|
||||
|
||||
function! coc#task#stop(id)
|
||||
let job = get(s:running_task, a:id, v:null)
|
||||
if !job | return | endif
|
||||
if s:is_vim
|
||||
call job_stop(job, 'term')
|
||||
else
|
||||
call jobstop(job)
|
||||
endif
|
||||
sleep 50m
|
||||
let running = coc#task#running(a:id)
|
||||
if running
|
||||
echohl Error | echom 'job '.a:id. ' stop failed.' | echohl None
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:on_exit(id, code) abort
|
||||
if get(g:, 'coc_vim_leaving', 0) | return | endif
|
||||
if has('nvim')
|
||||
let s:out_remain_text[a:id] = ''
|
||||
let s:err_remain_text[a:id] = ''
|
||||
endif
|
||||
if has_key(s:running_task, a:id)
|
||||
call remove(s:running_task, a:id)
|
||||
endif
|
||||
call coc#rpc#notify('TaskExit', [a:id, a:code])
|
||||
endfunction
|
||||
|
||||
function! s:on_stderr(id, msgs)
|
||||
if get(g:, 'coc_vim_leaving', 0) | return | endif
|
||||
if empty(a:msgs)
|
||||
return
|
||||
endif
|
||||
if s:is_vim
|
||||
call coc#rpc#notify('TaskStderr', [a:id, a:msgs])
|
||||
else
|
||||
let remain = get(s:err_remain_text, a:id, '')
|
||||
let eof = (a:msgs == [''])
|
||||
let msgs = copy(a:msgs)
|
||||
if len(remain) > 0
|
||||
if msgs[0] == ''
|
||||
let msgs[0] = remain
|
||||
else
|
||||
let msgs[0] = remain . msgs[0]
|
||||
endif
|
||||
endif
|
||||
let last = msgs[len(msgs) - 1]
|
||||
let s:err_remain_text[a:id] = len(last) > 0 ? last : ''
|
||||
" all lines from 0 to n - 2
|
||||
if len(msgs) > 1
|
||||
call coc#rpc#notify('TaskStderr', [a:id, msgs[:len(msgs)-2]])
|
||||
elseif eof && len(msgs[0]) > 0
|
||||
call coc#rpc#notify('TaskStderr', [a:id, msgs])
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:on_stdout(id, msgs)
|
||||
if empty(a:msgs)
|
||||
return
|
||||
endif
|
||||
if s:is_vim
|
||||
call coc#rpc#notify('TaskStdout', [a:id, a:msgs])
|
||||
else
|
||||
let remain = get(s:out_remain_text, a:id, '')
|
||||
let eof = (a:msgs == [''])
|
||||
let msgs = copy(a:msgs)
|
||||
if len(remain) > 0
|
||||
if msgs[0] == ''
|
||||
let msgs[0] = remain
|
||||
else
|
||||
let msgs[0] = remain . msgs[0]
|
||||
endif
|
||||
endif
|
||||
let last = msgs[len(msgs) - 1]
|
||||
let s:out_remain_text[a:id] = len(last) > 0 ? last : ''
|
||||
" all lines from 0 to n - 2
|
||||
if len(msgs) > 1
|
||||
call coc#rpc#notify('TaskStdout', [a:id, msgs[:len(msgs)-2]])
|
||||
elseif eof && len(msgs[0]) > 0
|
||||
call coc#rpc#notify('TaskStdout', [a:id, msgs])
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#task#running(id)
|
||||
if !has_key(s:running_task, a:id) == 1
|
||||
return v:false
|
||||
endif
|
||||
let job = s:running_task[a:id]
|
||||
if s:is_vim
|
||||
let status = job_status(job)
|
||||
return status ==# 'run'
|
||||
endif
|
||||
let [code] = jobwait([job], 10)
|
||||
return code == -1
|
||||
endfunction
|
|
@ -0,0 +1,115 @@
|
|||
scriptencoding utf-8
|
||||
let s:is_vim = !has('nvim')
|
||||
let s:channel_map = {}
|
||||
let s:is_win = has('win32') || has('win64')
|
||||
|
||||
" start terminal, return [bufnr, pid]
|
||||
function! coc#terminal#start(cmd, cwd, env) abort
|
||||
if s:is_vim && !has('terminal')
|
||||
throw 'terminal feature not supported by current vim.'
|
||||
endif
|
||||
let cwd = empty(a:cwd) ? getcwd() : a:cwd
|
||||
execute 'belowright 8new +setl\ buftype=nofile'
|
||||
setl winfixheight
|
||||
setl norelativenumber
|
||||
setl nonumber
|
||||
setl bufhidden=hide
|
||||
if exists('#User#CocTerminalOpen')
|
||||
exe 'doautocmd <nomodeline> User CocTerminalOpen'
|
||||
endif
|
||||
let bufnr = bufnr('%')
|
||||
let env = {}
|
||||
let original = {}
|
||||
if !empty(a:env)
|
||||
" use env option when possible
|
||||
if s:is_vim
|
||||
let env = copy(a:env)
|
||||
elseif exists('*setenv')
|
||||
for key in keys(a:env)
|
||||
let original[key] = getenv(key)
|
||||
call setenv(key, a:env[key])
|
||||
endfor
|
||||
endif
|
||||
endif
|
||||
|
||||
function! s:OnExit(status) closure
|
||||
if a:status == 0
|
||||
execute 'silent! bd! '.bufnr
|
||||
endif
|
||||
endfunction
|
||||
|
||||
if has('nvim')
|
||||
let job_id = termopen(a:cmd, {
|
||||
\ 'cwd': cwd,
|
||||
\ 'pty': 1,
|
||||
\ 'on_exit': {job, status -> s:OnExit(status)},
|
||||
\ 'env': env,
|
||||
\ })
|
||||
if !empty(original) && exists('*setenv')
|
||||
for key in keys(original)
|
||||
call setenv(key, original[key])
|
||||
endfor
|
||||
endif
|
||||
if job_id == 0
|
||||
throw 'create terminal job failed'
|
||||
endif
|
||||
wincmd p
|
||||
let s:channel_map[bufnr] = job_id
|
||||
return [bufnr, jobpid(job_id)]
|
||||
else
|
||||
let cmd = s:is_win ? join(a:cmd, ' ') : a:cmd
|
||||
let res = term_start(cmd, {
|
||||
\ 'cwd': cwd,
|
||||
\ 'term_kill': s:is_win ? 'kill' : 'term',
|
||||
\ 'term_finish': 'close',
|
||||
\ 'exit_cb': {job, status -> s:OnExit(status)},
|
||||
\ 'curwin': 1,
|
||||
\ 'env': env,
|
||||
\})
|
||||
if res == 0
|
||||
throw 'create terminal job failed'
|
||||
endif
|
||||
let job = term_getjob(bufnr)
|
||||
let s:channel_map[bufnr] = job_getchannel(job)
|
||||
wincmd p
|
||||
return [bufnr, job_info(job).process]
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#terminal#send(bufnr, text, add_new_line) abort
|
||||
let chan = get(s:channel_map, a:bufnr, v:null)
|
||||
if empty(chan) | return| endif
|
||||
if has('nvim')
|
||||
let lines = split(a:text, '\v\r?\n')
|
||||
if a:add_new_line && !empty(lines[len(lines) - 1])
|
||||
if s:is_win
|
||||
call add(lines, "\r\n")
|
||||
else
|
||||
call add(lines, '')
|
||||
endif
|
||||
endif
|
||||
call chansend(chan, lines)
|
||||
let winnr = bufwinnr(a:bufnr)
|
||||
if winnr != -1
|
||||
exe 'noa '.winnr.'wincmd w'
|
||||
exe 'noa normal! G'
|
||||
exe 'noa '.wincmd p
|
||||
endif
|
||||
else
|
||||
if !a:add_new_line
|
||||
call ch_sendraw(chan, a:text)
|
||||
else
|
||||
call ch_sendraw(chan, a:text.(s:is_win ? "\r\n" : "\n"))
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#terminal#close(bufnr) abort
|
||||
if has('nvim')
|
||||
let job_id = get(s:channel_map, a:bufnr, 0)
|
||||
if !empty(job_id)
|
||||
silent! call chanclose(job_id)
|
||||
endif
|
||||
endif
|
||||
exe 'silent! bd! '.a:bufnr
|
||||
endfunction
|
|
@ -0,0 +1,876 @@
|
|||
scriptencoding utf-8
|
||||
let s:root = expand('<sfile>:h:h:h')
|
||||
let s:is_win = has('win32') || has('win64')
|
||||
let s:is_vim = !has('nvim')
|
||||
let s:clear_match_by_id = has('nvim-0.5.0') || has('patch-8.1.1084')
|
||||
let s:vim_api_version = 10
|
||||
let s:activate = ""
|
||||
let s:quit = ""
|
||||
|
||||
if has("gui_macvim") && has('gui_running')
|
||||
let s:app = "MacVim"
|
||||
elseif $TERM_PROGRAM ==# "Apple_Terminal"
|
||||
let s:app = "Terminal"
|
||||
elseif $TERM_PROGRAM ==# "iTerm.app"
|
||||
let s:app = "iTerm2"
|
||||
elseif has('mac')
|
||||
let s:app = "System Events"
|
||||
let s:quit = "quit"
|
||||
let s:activate = 'activate'
|
||||
endif
|
||||
|
||||
function! coc#util#api_version() abort
|
||||
return s:vim_api_version
|
||||
endfunction
|
||||
|
||||
" get cursor position
|
||||
function! coc#util#cursor()
|
||||
return [line('.') - 1, strchars(strpart(getline('.'), 0, col('.') - 1))]
|
||||
endfunction
|
||||
|
||||
function! coc#util#has_preview()
|
||||
for i in range(1, winnr('$'))
|
||||
if getwinvar(i, '&previewwindow')
|
||||
return i
|
||||
endif
|
||||
endfor
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
function! coc#util#jumpTo(line, character) abort
|
||||
echohl WarningMsg | echon 'coc#util#jumpTo is deprecated, use coc#cursor#move_to instead.' | echohl None
|
||||
call coc#cursor#move_to(a:line, a:character)
|
||||
endfunction
|
||||
|
||||
function! coc#util#path_replace_patterns() abort
|
||||
if has('win32unix') && exists('g:coc_cygqwin_path_prefixes')
|
||||
echohl WarningMsg
|
||||
echon 'g:coc_cygqwin_path_prefixes is deprecated, use g:coc_uri_prefix_replace_patterns instead'
|
||||
echohl None
|
||||
return g:coc_cygqwin_path_prefixes
|
||||
endif
|
||||
if exists('g:coc_uri_prefix_replace_patterns')
|
||||
return g:coc_uri_prefix_replace_patterns
|
||||
endif
|
||||
return v:null
|
||||
endfunction
|
||||
|
||||
function! coc#util#version()
|
||||
if s:is_vim
|
||||
return string(v:versionlong)
|
||||
endif
|
||||
let c = execute('silent version')
|
||||
let lines = split(matchstr(c, 'NVIM v\zs[^\n-]*'))
|
||||
return lines[0]
|
||||
endfunction
|
||||
|
||||
function! coc#util#check_refresh(bufnr)
|
||||
if !bufloaded(a:bufnr)
|
||||
return 0
|
||||
endif
|
||||
if getbufvar(a:bufnr, 'coc_diagnostic_disable', 0)
|
||||
return 0
|
||||
endif
|
||||
if get(g: , 'EasyMotion_loaded', 0)
|
||||
return EasyMotion#is_active() != 1
|
||||
endif
|
||||
return 1
|
||||
endfunction
|
||||
|
||||
function! coc#util#diagnostic_info(bufnr, checkInsert) abort
|
||||
let checked = coc#util#check_refresh(a:bufnr)
|
||||
if !checked
|
||||
return v:null
|
||||
endif
|
||||
if a:checkInsert && mode() =~# '^i'
|
||||
return v:null
|
||||
endif
|
||||
let locationlist = ''
|
||||
let winid = -1
|
||||
for info in getwininfo()
|
||||
if info['bufnr'] == a:bufnr
|
||||
let winid = info['winid']
|
||||
let locationlist = get(getloclist(winid, {'title': 1}), 'title', '')
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
return {
|
||||
\ 'bufnr': bufnr('%'),
|
||||
\ 'winid': winid,
|
||||
\ 'lnum': line('.'),
|
||||
\ 'locationlist': locationlist
|
||||
\ }
|
||||
endfunction
|
||||
|
||||
function! coc#util#open_file(cmd, file)
|
||||
let file = fnameescape(a:file)
|
||||
execute a:cmd .' '.file
|
||||
endfunction
|
||||
|
||||
function! coc#util#remote_fns(name)
|
||||
let fns = ['init', 'complete', 'should_complete', 'refresh', 'get_startcol', 'on_complete', 'on_enter']
|
||||
let res = []
|
||||
for fn in fns
|
||||
if exists('*coc#source#'.a:name.'#'.fn)
|
||||
call add(res, fn)
|
||||
endif
|
||||
endfor
|
||||
return res
|
||||
endfunction
|
||||
|
||||
function! coc#util#job_command()
|
||||
if (has_key(g:, 'coc_node_path'))
|
||||
let node = expand(g:coc_node_path)
|
||||
else
|
||||
let node = $COC_NODE_PATH == '' ? 'node' : $COC_NODE_PATH
|
||||
endif
|
||||
if !executable(node)
|
||||
echohl Error | echom '[coc.nvim] "'.node.'" is not executable, checkout https://nodejs.org/en/download/' | echohl None
|
||||
return
|
||||
endif
|
||||
if !filereadable(s:root.'/build/index.js')
|
||||
if isdirectory(s:root.'/src')
|
||||
echohl Error | echom '[coc.nvim] build/index.js not found, please install dependencies and compile coc.nvim by: yarn install' | echohl None
|
||||
else
|
||||
echohl Error | echon '[coc.nvim] your coc.nvim is broken.' | echohl None
|
||||
endif
|
||||
return
|
||||
endif
|
||||
return [node] + get(g:, 'coc_node_args', ['--no-warnings']) + [s:root.'/build/index.js']
|
||||
endfunction
|
||||
|
||||
function! coc#util#echo_hover(msg)
|
||||
echohl MoreMsg
|
||||
echo a:msg
|
||||
echohl None
|
||||
let g:coc_last_hover_message = a:msg
|
||||
endfunction
|
||||
|
||||
function! coc#util#jump(cmd, filepath, ...) abort
|
||||
if a:cmd != 'pedit'
|
||||
silent! normal! m'
|
||||
endif
|
||||
let path = a:filepath
|
||||
if (has('win32unix'))
|
||||
let path = substitute(a:filepath, '\v\\', '/', 'g')
|
||||
endif
|
||||
let file = fnamemodify(path, ":~:.")
|
||||
if a:cmd == 'pedit'
|
||||
let extra = empty(get(a:, 1, [])) ? '' : '+'.(a:1[0] + 1)
|
||||
exe 'pedit '.extra.' '.fnameescape(file)
|
||||
return
|
||||
else
|
||||
exe a:cmd.' '.fnameescape(file)
|
||||
endif
|
||||
if !empty(get(a:, 1, []))
|
||||
let line = getline(a:1[0] + 1)
|
||||
" TODO need to use utf16 here
|
||||
let col = byteidx(line, a:1[1]) + 1
|
||||
if col == 0
|
||||
let col = 999
|
||||
endif
|
||||
call cursor(a:1[0] + 1, col)
|
||||
endif
|
||||
if &filetype ==# ''
|
||||
filetype detect
|
||||
endif
|
||||
if s:is_vim
|
||||
redraw
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#util#echo_messages(hl, msgs)
|
||||
if a:hl !~# 'Error' && (mode() !~# '\v^(i|n)$')
|
||||
return
|
||||
endif
|
||||
let msgs = filter(copy(a:msgs), '!empty(v:val)')
|
||||
if empty(msgs)
|
||||
return
|
||||
endif
|
||||
execute 'echohl '.a:hl
|
||||
echom a:msgs[0]
|
||||
redraw
|
||||
echo join(msgs, "\n")
|
||||
echohl None
|
||||
endfunction
|
||||
|
||||
function! coc#util#echo_lines(lines)
|
||||
echo join(a:lines, "\n")
|
||||
endfunction
|
||||
|
||||
function! coc#util#timer(method, args)
|
||||
call timer_start(0, { -> s:Call(a:method, a:args)})
|
||||
endfunction
|
||||
|
||||
function! s:Call(method, args)
|
||||
try
|
||||
call call(a:method, a:args)
|
||||
redraw
|
||||
catch /.*/
|
||||
return 0
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! coc#util#get_bufoptions(bufnr, maxFileSize) abort
|
||||
if !bufloaded(a:bufnr) | return v:null | endif
|
||||
let bufname = bufname(a:bufnr)
|
||||
let buftype = getbufvar(a:bufnr, '&buftype')
|
||||
let winid = bufwinid(a:bufnr)
|
||||
let size = -1
|
||||
if bufnr('%') == a:bufnr
|
||||
let size = line2byte(line("$") + 1)
|
||||
elseif !empty(bufname)
|
||||
let size = getfsize(bufname)
|
||||
endif
|
||||
let lines = []
|
||||
if getbufvar(a:bufnr, 'coc_enabled', 1) && (buftype == '' || buftype == 'acwrite') && size < a:maxFileSize
|
||||
let lines = getbufline(a:bufnr, 1, '$')
|
||||
endif
|
||||
return {
|
||||
\ 'bufname': bufname,
|
||||
\ 'size': size,
|
||||
\ 'buftype': buftype,
|
||||
\ 'winid': winid,
|
||||
\ 'previewwindow': v:false,
|
||||
\ 'variables': s:variables(a:bufnr),
|
||||
\ 'fullpath': empty(bufname) ? '' : fnamemodify(bufname, ':p'),
|
||||
\ 'eol': getbufvar(a:bufnr, '&eol'),
|
||||
\ 'filetype': getbufvar(a:bufnr, '&filetype'),
|
||||
\ 'iskeyword': getbufvar(a:bufnr, '&iskeyword'),
|
||||
\ 'changedtick': getbufvar(a:bufnr, 'changedtick'),
|
||||
\ 'lines': lines,
|
||||
\}
|
||||
endfunction
|
||||
|
||||
function! s:variables(bufnr) abort
|
||||
let info = getbufinfo(a:bufnr)
|
||||
let variables = empty(info) ? {} : copy(info[0]['variables'])
|
||||
for key in keys(variables)
|
||||
if key !~# '\v^coc'
|
||||
unlet variables[key]
|
||||
endif
|
||||
endfor
|
||||
return variables
|
||||
endfunction
|
||||
|
||||
function! coc#util#root_patterns() abort
|
||||
return coc#rpc#request('rootPatterns', [bufnr('%')])
|
||||
endfunction
|
||||
|
||||
function! coc#util#get_config(key) abort
|
||||
return coc#rpc#request('getConfig', [a:key])
|
||||
endfunction
|
||||
|
||||
function! coc#util#preview_info(info, filetype, ...) abort
|
||||
pclose
|
||||
keepalt new +setlocal\ previewwindow|setlocal\ buftype=nofile|setlocal\ noswapfile|setlocal\ wrap [Document]
|
||||
setl bufhidden=wipe
|
||||
setl nobuflisted
|
||||
setl nospell
|
||||
exe 'setl filetype='.a:filetype
|
||||
setl conceallevel=0
|
||||
setl nofoldenable
|
||||
for command in a:000
|
||||
execute command
|
||||
endfor
|
||||
let lines = a:info
|
||||
call append(0, lines)
|
||||
exe "normal! z" . len(lines) . "\<cr>"
|
||||
exe "normal! gg"
|
||||
wincmd p
|
||||
endfunction
|
||||
|
||||
function! coc#util#get_config_home()
|
||||
if !empty(get(g:, 'coc_config_home', ''))
|
||||
return resolve(expand(g:coc_config_home))
|
||||
endif
|
||||
if exists('$VIMCONFIG')
|
||||
return resolve($VIMCONFIG)
|
||||
endif
|
||||
if has('nvim')
|
||||
if exists('$XDG_CONFIG_HOME')
|
||||
return resolve($XDG_CONFIG_HOME."/nvim")
|
||||
endif
|
||||
if s:is_win
|
||||
return resolve($HOME.'/AppData/Local/nvim')
|
||||
endif
|
||||
return resolve($HOME.'/.config/nvim')
|
||||
else
|
||||
if s:is_win
|
||||
return resolve($HOME."/vimfiles")
|
||||
endif
|
||||
return resolve($HOME.'/.vim')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#util#get_data_home()
|
||||
if !empty(get(g:, 'coc_data_home', ''))
|
||||
let dir = resolve(expand(g:coc_data_home))
|
||||
else
|
||||
if exists('$XDG_CONFIG_HOME')
|
||||
let dir = resolve($XDG_CONFIG_HOME."/coc")
|
||||
else
|
||||
if s:is_win
|
||||
let dir = resolve(expand('~/AppData/Local/coc'))
|
||||
else
|
||||
let dir = resolve(expand('~/.config/coc'))
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
if !isdirectory(dir)
|
||||
echohl MoreMsg | echom '[coc.nvim] creating data directory: '.dir | echohl None
|
||||
call mkdir(dir, "p", 0755)
|
||||
endif
|
||||
return dir
|
||||
endfunction
|
||||
|
||||
function! coc#util#get_input()
|
||||
let before = strpart(getline('.'), 0, col('.')-1)
|
||||
if len(before) == 0
|
||||
return ''
|
||||
endif
|
||||
return matchstr(before, '\k*$')
|
||||
endfunction
|
||||
|
||||
function! coc#util#get_complete_option()
|
||||
let pos = getcurpos()
|
||||
let line = getline(pos[1])
|
||||
let input = matchstr(strpart(line, 0, pos[2] - 1), '\k*$')
|
||||
let col = pos[2] - strlen(input)
|
||||
let synname = synIDattr(synID(pos[1], col, 1), 'name')
|
||||
return {
|
||||
\ 'word': matchstr(strpart(line, col - 1), '^\k\+'),
|
||||
\ 'input': empty(input) ? '' : input,
|
||||
\ 'line': line,
|
||||
\ 'filetype': &filetype,
|
||||
\ 'filepath': expand('%:p'),
|
||||
\ 'bufnr': bufnr('%'),
|
||||
\ 'linenr': pos[1],
|
||||
\ 'colnr' : pos[2],
|
||||
\ 'col': col - 1,
|
||||
\ 'synname': synname,
|
||||
\ 'changedtick': b:changedtick,
|
||||
\ 'blacklist': get(b:, 'coc_suggest_blacklist', []),
|
||||
\}
|
||||
endfunction
|
||||
|
||||
function! coc#util#with_callback(method, args, cb)
|
||||
function! s:Cb() closure
|
||||
try
|
||||
let res = call(a:method, a:args)
|
||||
call a:cb(v:null, res)
|
||||
catch /.*/
|
||||
call a:cb(v:exception)
|
||||
endtry
|
||||
endfunction
|
||||
let timeout = s:is_vim ? 10 : 0
|
||||
call timer_start(timeout, {-> s:Cb() })
|
||||
endfunction
|
||||
|
||||
function! coc#util#quickpick(title, items, cb) abort
|
||||
if exists('*popup_menu')
|
||||
function! s:QuickpickHandler(id, result) closure
|
||||
call a:cb(v:null, a:result)
|
||||
endfunction
|
||||
function! s:QuickpickFilter(id, key) closure
|
||||
for i in range(1, len(a:items))
|
||||
if a:key == string(i)
|
||||
call popup_close(a:id, i)
|
||||
return 1
|
||||
endif
|
||||
endfor
|
||||
" No shortcut, pass to generic filter
|
||||
return popup_filter_menu(a:id, a:key)
|
||||
endfunction
|
||||
try
|
||||
call popup_menu(a:items, {
|
||||
\ 'title': a:title,
|
||||
\ 'filter': function('s:QuickpickFilter'),
|
||||
\ 'callback': function('s:QuickpickHandler'),
|
||||
\ })
|
||||
redraw
|
||||
catch /.*/
|
||||
call a:cb(v:exception)
|
||||
endtry
|
||||
else
|
||||
let res = inputlist([a:title] + a:items)
|
||||
call a:cb(v:null, res)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#util#echo_signatures(signatures) abort
|
||||
if pumvisible() | return | endif
|
||||
echo ""
|
||||
for i in range(len(a:signatures))
|
||||
call s:echo_signature(a:signatures[i])
|
||||
if i != len(a:signatures) - 1
|
||||
echon "\n"
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! s:echo_signature(parts)
|
||||
for part in a:parts
|
||||
let hl = get(part, 'type', 'Normal')
|
||||
let text = get(part, 'text', '')
|
||||
if !empty(text)
|
||||
execute 'echohl '.hl
|
||||
execute "echon '".substitute(text, "'", "''", 'g')."'"
|
||||
echohl None
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! coc#util#setline(lnum, line)
|
||||
keepjumps call setline(a:lnum, a:line)
|
||||
endfunction
|
||||
|
||||
" cmd, cwd
|
||||
function! coc#util#open_terminal(opts) abort
|
||||
if s:is_vim && !exists('*term_start')
|
||||
echohl WarningMsg | echon "Your vim doesn't have terminal support!" | echohl None
|
||||
return
|
||||
endif
|
||||
if get(a:opts, 'position', 'bottom') ==# 'bottom'
|
||||
let p = '5new'
|
||||
else
|
||||
let p = 'vnew'
|
||||
endif
|
||||
execute 'belowright '.p.' +setl\ buftype=nofile '
|
||||
setl buftype=nofile
|
||||
setl winfixheight
|
||||
setl norelativenumber
|
||||
setl nonumber
|
||||
setl bufhidden=wipe
|
||||
let cmd = get(a:opts, 'cmd', '')
|
||||
let autoclose = get(a:opts, 'autoclose', 1)
|
||||
if empty(cmd)
|
||||
throw 'command required!'
|
||||
endif
|
||||
let cwd = get(a:opts, 'cwd', getcwd())
|
||||
let keepfocus = get(a:opts, 'keepfocus', 0)
|
||||
let bufnr = bufnr('%')
|
||||
let Callback = get(a:opts, 'Callback', v:null)
|
||||
|
||||
function! s:OnExit(status) closure
|
||||
let content = join(getbufline(bufnr, 1, '$'), "\n")
|
||||
if a:status == 0 && autoclose == 1
|
||||
execute 'silent! bd! '.bufnr
|
||||
endif
|
||||
if !empty(Callback)
|
||||
call call(Callback, [a:status, bufnr, content])
|
||||
endif
|
||||
endfunction
|
||||
|
||||
if has('nvim')
|
||||
call termopen(cmd, {
|
||||
\ 'cwd': cwd,
|
||||
\ 'on_exit': {job, status -> s:OnExit(status)},
|
||||
\})
|
||||
else
|
||||
if s:is_win
|
||||
let cmd = 'cmd.exe /C "'.cmd.'"'
|
||||
endif
|
||||
call term_start(cmd, {
|
||||
\ 'cwd': cwd,
|
||||
\ 'exit_cb': {job, status -> s:OnExit(status)},
|
||||
\ 'curwin': 1,
|
||||
\})
|
||||
endif
|
||||
if keepfocus
|
||||
wincmd p
|
||||
endif
|
||||
return bufnr
|
||||
endfunction
|
||||
|
||||
" run command in terminal
|
||||
function! coc#util#run_terminal(opts, cb)
|
||||
let cmd = get(a:opts, 'cmd', '')
|
||||
if empty(cmd)
|
||||
return a:cb('command required for terminal')
|
||||
endif
|
||||
let opts = {
|
||||
\ 'cmd': cmd,
|
||||
\ 'cwd': get(a:opts, 'cwd', getcwd()),
|
||||
\ 'keepfocus': get(a:opts, 'keepfocus', 0),
|
||||
\ 'Callback': {status, bufnr, content -> a:cb(v:null, {'success': status == 0 ? v:true : v:false, 'bufnr': bufnr, 'content': content})}
|
||||
\}
|
||||
call coc#util#open_terminal(opts)
|
||||
endfunction
|
||||
|
||||
function! coc#util#getpid()
|
||||
if !has('win32unix')
|
||||
return getpid()
|
||||
endif
|
||||
let cmd = 'cat /proc/' . getpid() . '/winpid'
|
||||
return substitute(system(cmd), '\v\n', '', 'gi')
|
||||
endfunction
|
||||
|
||||
function! coc#util#vim_info()
|
||||
return {
|
||||
\ 'apiversion': s:vim_api_version,
|
||||
\ 'mode': mode(),
|
||||
\ 'floating': has('nvim') && exists('*nvim_open_win') ? v:true : v:false,
|
||||
\ 'extensionRoot': coc#util#extension_root(),
|
||||
\ 'globalExtensions': get(g:, 'coc_global_extensions', []),
|
||||
\ 'config': get(g:, 'coc_user_config', {}),
|
||||
\ 'pid': coc#util#getpid(),
|
||||
\ 'columns': &columns,
|
||||
\ 'lines': &lines,
|
||||
\ 'cmdheight': &cmdheight,
|
||||
\ 'filetypeMap': get(g:, 'coc_filetype_map', {}),
|
||||
\ 'version': coc#util#version(),
|
||||
\ 'completeOpt': &completeopt,
|
||||
\ 'pumevent': exists('##MenuPopupChanged') || exists('##CompleteChanged'),
|
||||
\ 'isVim': has('nvim') ? v:false : v:true,
|
||||
\ 'isCygwin': has('win32unix') ? v:true : v:false,
|
||||
\ 'isMacvim': has('gui_macvim') ? v:true : v:false,
|
||||
\ 'isiTerm': $TERM_PROGRAM ==# "iTerm.app",
|
||||
\ 'colorscheme': get(g:, 'colors_name', ''),
|
||||
\ 'workspaceFolders': get(g:, 'WorkspaceFolders', v:null),
|
||||
\ 'background': &background,
|
||||
\ 'runtimepath': &runtimepath,
|
||||
\ 'locationlist': get(g:,'coc_enable_locationlist', 1),
|
||||
\ 'progpath': v:progpath,
|
||||
\ 'guicursor': &guicursor,
|
||||
\ 'updateHighlight': has('nvim-0.5.0') || exists('*prop_list') ? v:true : v:false,
|
||||
\ 'vimCommands': get(g:, 'coc_vim_commands', []),
|
||||
\ 'sign': exists('*sign_place') && exists('*sign_unplace'),
|
||||
\ 'textprop': has('textprop') && has('patch-8.1.1719') && !has('nvim') ? v:true : v:false,
|
||||
\ 'dialog': has('nvim-0.4.0') || has('patch-8.2.0750') ? v:true : v:false,
|
||||
\ 'disabledSources': get(g:, 'coc_sources_disable_map', {}),
|
||||
\}
|
||||
endfunction
|
||||
|
||||
function! coc#util#highlight_options()
|
||||
return {
|
||||
\ 'colorscheme': get(g:, 'colors_name', ''),
|
||||
\ 'background': &background,
|
||||
\ 'runtimepath': &runtimepath,
|
||||
\}
|
||||
endfunction
|
||||
|
||||
function! coc#util#set_lines(bufnr, changedtick, original, replacement, start, end) abort
|
||||
if !bufloaded(a:bufnr)
|
||||
return
|
||||
endif
|
||||
if getbufvar(a:bufnr, 'changedtick') != a:changedtick && bufnr('%') == a:bufnr
|
||||
" try apply current line change
|
||||
let lnum = line('.')
|
||||
let idx = a:start - lnum + 1
|
||||
let previous = get(a:original, idx, 0)
|
||||
if type(previous) == 1
|
||||
let content = getline('.')
|
||||
if previous !=# content
|
||||
let diff = coc#helper#str_diff(content, previous, col('.'))
|
||||
let changed = get(a:replacement, idx, 0)
|
||||
if type(changed) == 1 && strcharpart(previous, 0, diff['end']) ==# strcharpart(changed, 0, diff['end'])
|
||||
let applied = coc#helper#str_apply(changed, diff)
|
||||
let replacement = copy(a:replacement)
|
||||
let replacement[idx] = applied
|
||||
call coc#compat#buf_set_lines(a:bufnr, a:start, a:end, replacement)
|
||||
return
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
call coc#compat#buf_set_lines(a:bufnr, a:start, a:end, a:replacement)
|
||||
endfunction
|
||||
|
||||
function! coc#util#change_lines(bufnr, list) abort
|
||||
if !bufloaded(a:bufnr) | return v:null | endif
|
||||
undojoin
|
||||
if exists('*setbufline')
|
||||
for [lnum, line] in a:list
|
||||
call setbufline(a:bufnr, lnum + 1, line)
|
||||
endfor
|
||||
elseif a:bufnr == bufnr('%')
|
||||
for [lnum, line] in a:list
|
||||
call setline(lnum + 1, line)
|
||||
endfor
|
||||
else
|
||||
let bufnr = bufnr('%')
|
||||
exe 'noa buffer '.a:bufnr
|
||||
for [lnum, line] in a:list
|
||||
call setline(lnum + 1, line)
|
||||
endfor
|
||||
exe 'noa buffer '.bufnr
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
" used by vim
|
||||
function! coc#util#get_buf_lines(bufnr, changedtick)
|
||||
if !bufloaded(a:bufnr)
|
||||
return v:null
|
||||
endif
|
||||
let changedtick = getbufvar(a:bufnr, 'changedtick')
|
||||
if changedtick == a:changedtick
|
||||
return v:null
|
||||
endif
|
||||
return {
|
||||
\ 'lines': getbufline(a:bufnr, 1, '$'),
|
||||
\ 'changedtick': getbufvar(a:bufnr, 'changedtick')
|
||||
\ }
|
||||
endfunction
|
||||
|
||||
" used for TextChangedI with InsertCharPre
|
||||
function! coc#util#get_changeinfo()
|
||||
return {
|
||||
\ 'lnum': line('.'),
|
||||
\ 'line': getline('.'),
|
||||
\ 'changedtick': b:changedtick,
|
||||
\}
|
||||
endfunction
|
||||
|
||||
function! coc#util#open_url(url)
|
||||
if has('mac') && executable('open')
|
||||
call system('open '.a:url)
|
||||
return
|
||||
endif
|
||||
if executable('xdg-open')
|
||||
call system('xdg-open '.a:url)
|
||||
return
|
||||
endif
|
||||
call system('cmd /c start "" /b '. substitute(a:url, '&', '^&', 'g'))
|
||||
if v:shell_error
|
||||
echohl Error | echom 'Failed to open '.a:url | echohl None
|
||||
return
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#util#install() abort
|
||||
let yarncmd = get(g:, 'coc_install_yarn_cmd', executable('yarnpkg') ? 'yarnpkg' : 'yarn')
|
||||
call coc#util#open_terminal({
|
||||
\ 'cwd': s:root,
|
||||
\ 'cmd': yarncmd.' install --frozen-lockfile --ignore-engines',
|
||||
\ 'autoclose': 0,
|
||||
\ })
|
||||
endfunction
|
||||
|
||||
function! coc#util#do_complete(name, opt, cb) abort
|
||||
let handler = 'coc#source#'.a:name.'#complete'
|
||||
let l:Cb = {res -> a:cb(v:null, res)}
|
||||
let args = [a:opt, l:Cb]
|
||||
call call(handler, args)
|
||||
endfunction
|
||||
|
||||
function! coc#util#extension_root() abort
|
||||
if get(g:, 'coc_node_env', '') ==# 'test'
|
||||
return s:root.'/src/__tests__/extensions'
|
||||
endif
|
||||
if !empty(get(g:, 'coc_extension_root', ''))
|
||||
echohl Error | echon 'g:coc_extension_root not used any more, use g:coc_data_home instead' | echohl None
|
||||
endif
|
||||
return coc#util#get_data_home().'/extensions'
|
||||
endfunction
|
||||
|
||||
function! coc#util#update_extensions(...) abort
|
||||
let async = get(a:, 1, 0)
|
||||
if async
|
||||
call coc#rpc#notify('updateExtensions', [])
|
||||
else
|
||||
call coc#rpc#request('updateExtensions', [v:true])
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#util#install_extension(args) abort
|
||||
let names = filter(copy(a:args), 'v:val !~# "^-"')
|
||||
let isRequest = index(a:args, '-sync') != -1
|
||||
if isRequest
|
||||
call coc#rpc#request('installExtensions', names)
|
||||
else
|
||||
call coc#rpc#notify('installExtensions', names)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#util#do_autocmd(name) abort
|
||||
if exists('#User#'.a:name)
|
||||
exe 'doautocmd <nomodeline> User '.a:name
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#util#rebuild()
|
||||
let dir = coc#util#extension_root()
|
||||
if !isdirectory(dir) | return | endif
|
||||
call coc#util#open_terminal({
|
||||
\ 'cwd': dir,
|
||||
\ 'cmd': 'npm rebuild',
|
||||
\ 'keepfocus': 1,
|
||||
\})
|
||||
endfunction
|
||||
|
||||
" [r, g, b] ['255', '255', '255']
|
||||
" return ['65535', '65535', '65535'] or return v:false to cancel
|
||||
function! coc#util#pick_color(default_color)
|
||||
if has('mac')
|
||||
let default_color = map(a:default_color, {idx, val -> str2nr(val) * 65535 / 255 })
|
||||
" This is the AppleScript magic:
|
||||
let s:ascrpt = ['-e "tell application \"' . s:app . '\""',
|
||||
\ '-e "' . s:activate . '"',
|
||||
\ "-e \"set AppleScript's text item delimiters to {\\\",\\\"}\"",
|
||||
\ '-e "set theColor to (choose color default color {' . default_color[0] . ", " . default_color[1] . ", " . default_color[2] . '}) as text"',
|
||||
\ '-e "' . s:quit . '"',
|
||||
\ '-e "end tell"',
|
||||
\ '-e "return theColor"']
|
||||
let res = trim(system("osascript " . join(s:ascrpt, ' ') . " 2>/dev/null"))
|
||||
if empty(res)
|
||||
return v:false
|
||||
else
|
||||
return split(trim(res), ',')
|
||||
endif
|
||||
endif
|
||||
|
||||
let hex_color = printf('#%02x%02x%02x', a:default_color[0], a:default_color[1], a:default_color[2])
|
||||
|
||||
if has('unix')
|
||||
if executable('zenity')
|
||||
let res = trim(system('zenity --title="Select a color" --color-selection --color="' . hex_color . '" 2> /dev/null'))
|
||||
if empty(res)
|
||||
return v:false
|
||||
else
|
||||
" res format is rgb(255,255,255)
|
||||
return map(split(res[4:-2], ','), {idx, val -> string(str2nr(trim(val)) * 65535 / 255)})
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
let rgb = v:false
|
||||
if !has('python')
|
||||
echohl Error | echom 'python support required, checkout :echo has(''python'')' | echohl None
|
||||
return
|
||||
endif
|
||||
try
|
||||
execute 'py import gtk'
|
||||
catch /.*/
|
||||
echohl Error | echom 'python gtk module not found' | echohl None
|
||||
return
|
||||
endtry
|
||||
python << endpython
|
||||
|
||||
import vim
|
||||
import gtk, sys
|
||||
|
||||
# message strings
|
||||
wnd_title_insert = "Insert a color"
|
||||
|
||||
csd = gtk.ColorSelectionDialog(wnd_title_insert)
|
||||
cs = csd.colorsel
|
||||
|
||||
cs.set_current_color(gtk.gdk.color_parse(vim.eval("hex_color")))
|
||||
|
||||
cs.set_current_alpha(65535)
|
||||
cs.set_has_opacity_control(False)
|
||||
# cs.set_has_palette(int(vim.eval("s:display_palette")))
|
||||
|
||||
if csd.run()==gtk.RESPONSE_OK:
|
||||
c = cs.get_current_color()
|
||||
s = [str(int(c.red)),',',str(int(c.green)),',',str(int(c.blue))]
|
||||
thecolor = ''.join(s)
|
||||
vim.command(":let rgb = split('%s',',')" % thecolor)
|
||||
|
||||
csd.destroy()
|
||||
|
||||
endpython
|
||||
return rgb
|
||||
endfunction
|
||||
|
||||
function! coc#util#iterm_open(dir)
|
||||
return s:osascript(
|
||||
\ 'if application "iTerm2" is not running',
|
||||
\ 'error',
|
||||
\ 'end if') && s:osascript(
|
||||
\ 'tell application "iTerm2"',
|
||||
\ 'tell current window',
|
||||
\ 'create tab with default profile',
|
||||
\ 'tell current session',
|
||||
\ 'write text "cd ' . a:dir . '"',
|
||||
\ 'write text "clear"',
|
||||
\ 'activate',
|
||||
\ 'end tell',
|
||||
\ 'end tell',
|
||||
\ 'end tell')
|
||||
endfunction
|
||||
|
||||
function! s:osascript(...) abort
|
||||
let args = join(map(copy(a:000), '" -e ".shellescape(v:val)'), '')
|
||||
call s:system('osascript'. args)
|
||||
return !v:shell_error
|
||||
endfunction
|
||||
|
||||
function! s:system(cmd)
|
||||
let output = system(a:cmd)
|
||||
if v:shell_error && output !=# ""
|
||||
echohl Error | echom output | echohl None
|
||||
return
|
||||
endif
|
||||
return output
|
||||
endfunction
|
||||
|
||||
function! coc#util#unmap(bufnr, keys) abort
|
||||
if bufnr('%') == a:bufnr
|
||||
for key in a:keys
|
||||
exe 'silent! nunmap <buffer> '.key
|
||||
endfor
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! coc#util#open_files(files)
|
||||
let bufnrs = []
|
||||
" added on latest vim8
|
||||
if exists('*bufadd') && exists('*bufload')
|
||||
for file in a:files
|
||||
let file = fnamemodify(file, ':.')
|
||||
if bufloaded(file)
|
||||
call add(bufnrs, bufnr(file))
|
||||
else
|
||||
let bufnr = bufadd(file)
|
||||
call bufload(file)
|
||||
call add(bufnrs, bufnr)
|
||||
call setbufvar(bufnr, '&buflisted', 1)
|
||||
endif
|
||||
endfor
|
||||
else
|
||||
noa keepalt 1new +setl\ bufhidden=wipe
|
||||
for file in a:files
|
||||
let file = fnamemodify(file, ':.')
|
||||
execute 'noa edit +setl\ bufhidden=hide '.fnameescape(file)
|
||||
if &filetype ==# ''
|
||||
filetype detect
|
||||
endif
|
||||
call add(bufnrs, bufnr('%'))
|
||||
endfor
|
||||
noa close
|
||||
endif
|
||||
doautocmd BufEnter
|
||||
return bufnrs
|
||||
endfunction
|
||||
|
||||
function! coc#util#refactor_foldlevel(lnum) abort
|
||||
if a:lnum <= 2 | return 0 | endif
|
||||
let line = getline(a:lnum)
|
||||
if line =~# '^\%u3000\s*$' | return 0 | endif
|
||||
return 1
|
||||
endfunction
|
||||
|
||||
function! coc#util#refactor_fold_text(lnum) abort
|
||||
let range = ''
|
||||
let info = get(b:line_infos, a:lnum, [])
|
||||
if !empty(info)
|
||||
let range = info[0].':'.info[1]
|
||||
endif
|
||||
return trim(getline(a:lnum)[3:]).' '.range
|
||||
endfunction
|
||||
|
||||
" get tabsize & expandtab option
|
||||
function! coc#util#get_format_opts(bufnr) abort
|
||||
if a:bufnr && bufloaded(a:bufnr)
|
||||
let tabsize = getbufvar(a:bufnr, '&shiftwidth')
|
||||
if tabsize == 0
|
||||
let tabsize = getbufvar(a:bufnr, '&tabstop')
|
||||
endif
|
||||
return [tabsize, getbufvar(a:bufnr, '&expandtab')]
|
||||
endif
|
||||
let tabsize = &shiftwidth == 0 ? &tabstop : &shiftwidth
|
||||
return [tabsize, &expandtab]
|
||||
endfunction
|
|
@ -0,0 +1,56 @@
|
|||
function! coc#window#tabnr(winid) abort
|
||||
if exists('*win_execute')
|
||||
let ref = {}
|
||||
call win_execute(a:winid, 'let ref["out"] = tabpagenr()')
|
||||
return get(ref, 'out', -1)
|
||||
elseif has('nvim')
|
||||
let info = getwininfo(a:winid)
|
||||
return empty(info) ? -1 : info[0]['tabnr']
|
||||
else
|
||||
throw 'win_execute() not exists, please upgrade your vim.'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Get single window by window variable, current tab only
|
||||
function! coc#window#find(key, val) abort
|
||||
for i in range(1, winnr('$'))
|
||||
let res = getwinvar(i, a:key)
|
||||
if res == a:val
|
||||
return win_getid(i)
|
||||
endif
|
||||
endfor
|
||||
return -1
|
||||
endfunction
|
||||
|
||||
" Make sure window exists
|
||||
function! coc#window#gotoid(winid) abort
|
||||
noa let res = win_gotoid(a:winid)
|
||||
if res == 0
|
||||
throw 'Invalid window number'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Avoid autocmd & errors
|
||||
function! coc#window#close(winid) abort
|
||||
if empty(a:winid) || a:winid == -1
|
||||
return
|
||||
endif
|
||||
if exists('*nvim_win_is_valid') && exists('*nvim_win_close')
|
||||
if nvim_win_is_valid(a:winid)
|
||||
noa call nvim_win_close(a:winid, 1)
|
||||
endif
|
||||
elseif exists('*win_execute')
|
||||
call coc#compat#execute(a:winid, 'noa close!', 'silent!')
|
||||
else
|
||||
let curr = win_getid()
|
||||
if curr == a:winid
|
||||
noa silent! close!
|
||||
else
|
||||
let res = win_gotoid(a:winid)
|
||||
if res
|
||||
noa silent! close!
|
||||
noa call win_gotoid(curr)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endfunction
|
|
@ -0,0 +1,86 @@
|
|||
scriptencoding utf-8
|
||||
let s:root = expand('<sfile>:h:h:h')
|
||||
|
||||
function! s:checkEnvironment() abort
|
||||
let valid = 1
|
||||
if !has('nvim-0.3.0')
|
||||
let valid = 0
|
||||
call health#report_error('Neovim version not satisfied, 0.3.0 and above required')
|
||||
endif
|
||||
let node = get(g:, 'coc_node_path', $COC_NODE_PATH == '' ? 'node' : $COC_NODE_PATH)
|
||||
if !executable(node)
|
||||
let valid = 0
|
||||
call health#report_error('Executable node.js not found, install node.js from http://nodejs.org/')
|
||||
endif
|
||||
let output = system(node . ' --version')
|
||||
if v:shell_error && output !=# ""
|
||||
let valid = 0
|
||||
call health#report_error(output)
|
||||
endif
|
||||
let ms = matchlist(output, 'v\(\d\+\).\(\d\+\).\(\d\+\)')
|
||||
if empty(ms)
|
||||
let valid = 0
|
||||
call health#report_error('Unable to detect version of node, make sure your node executable is http://nodejs.org/')
|
||||
elseif str2nr(ms[1]) < 12 || (str2nr(ms[1]) == 12 && str2nr(ms[2]) < 12)
|
||||
let valid = 0
|
||||
call health#report_warn('Node.js version '.trim(output).' < 12.12.0, please upgrade node.js')
|
||||
endif
|
||||
if valid
|
||||
call health#report_ok('Environment check passed')
|
||||
endif
|
||||
if has('pythonx')
|
||||
try
|
||||
silent pyx print("")
|
||||
catch /.*/
|
||||
call health#report_warn('pyx command not work, some extensions may fail to work, checkout ":h pythonx"')
|
||||
endtry
|
||||
endif
|
||||
return valid
|
||||
endfunction
|
||||
|
||||
function! s:checkCommand()
|
||||
let file = s:root.'/build/index.js'
|
||||
if filereadable(file)
|
||||
call health#report_ok('Javascript bundle build/index.js found')
|
||||
else
|
||||
call health#report_error('Javascript entry not found, please compile coc.nvim by esbuild.')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:checkAutocmd()
|
||||
let cmds = ['CursorHold', 'CursorHoldI', 'CursorMovedI', 'InsertCharPre', 'TextChangedI']
|
||||
for cmd in cmds
|
||||
let lines = split(execute('verbose autocmd '.cmd), '\n')
|
||||
let n = 0
|
||||
for line in lines
|
||||
if line =~# 'CocAction(' && n < len(lines) - 1
|
||||
let next = lines[n + 1]
|
||||
let ms = matchlist(next, 'Last set from \(.*\)')
|
||||
if !empty(ms)
|
||||
call health#report_warn('Use CocActionAsync to replace CocAction for better performance on '.cmd)
|
||||
call health#report_warn('Checkout the file '.ms[1])
|
||||
endif
|
||||
endif
|
||||
let n = n + 1
|
||||
endfor
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! s:checkInitailize() abort
|
||||
if coc#client#is_running('coc')
|
||||
call health#report_ok('Service started')
|
||||
return 1
|
||||
endif
|
||||
call health#report_error('service could not be initialized', [
|
||||
\ 'Use command ":messages" to get error messages.',
|
||||
\ 'Open a issue at https://github.com/neoclide/coc.nvim/issues for feedback.'
|
||||
\])
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
function! health#coc#check() abort
|
||||
call s:checkEnvironment()
|
||||
call s:checkCommand()
|
||||
call s:checkInitailize()
|
||||
call s:checkAutocmd()
|
||||
endfunction
|
|
@ -0,0 +1,12 @@
|
|||
#!/bin/bash
|
||||
terminateTree() {
|
||||
for cpid in $(pgrep -P $1); do
|
||||
terminateTree $cpid
|
||||
done
|
||||
kill -9 $1 > /dev/null 2>&1
|
||||
}
|
||||
|
||||
for pid in $*; do
|
||||
terminateTree $pid
|
||||
done
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Used for prompt popup on vim
|
||||
*/
|
||||
const readline = require("readline")
|
||||
const rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout,
|
||||
escapeCodeTimeout: 0
|
||||
})
|
||||
rl.setPrompt('')
|
||||
let value = process.argv[2]
|
||||
if (value) {
|
||||
rl.write(value)
|
||||
}
|
||||
rl.on('line', input => {
|
||||
let text = input.replace(/"/g, '\\"')
|
||||
console.log(createSequences(JSON.stringify(['call', 'CocPopupCallback', ['confirm', text]])))
|
||||
process.exit()
|
||||
})
|
||||
|
||||
function createSequences(str) {
|
||||
return '\033]51;' + str + '\x07'
|
||||
}
|
||||
|
||||
process.stdin.on('keypress', (_, key) => {
|
||||
if (key) {
|
||||
let k = getKey(key)
|
||||
if (k == '<bs>') {
|
||||
return
|
||||
}
|
||||
if (k == '<cr>') {
|
||||
process.exit()
|
||||
return
|
||||
}
|
||||
if (k == '<esc>') {
|
||||
console.log(createSequences(JSON.stringify(['call', 'CocPopupCallback', ['exit', '']])))
|
||||
process.exit()
|
||||
return
|
||||
}
|
||||
if (k) {
|
||||
console.log(createSequences(JSON.stringify(['call', 'CocPopupCallback', ['send', k]])))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
function getKey(key) {
|
||||
if (key.sequence == '\u001b') {
|
||||
return '<esc>'
|
||||
}
|
||||
if (key.sequence == '\r') {
|
||||
return '<cr>'
|
||||
}
|
||||
if (key.sequence == '\t') {
|
||||
return key.shift ? '<s-tab>' : '<tab>'
|
||||
}
|
||||
// handle them can cause bug with terminal
|
||||
// if (key.name == 'backspace') {
|
||||
// return '<bs>'
|
||||
// }
|
||||
// if (key.name == 'left') {
|
||||
// return '<left>'
|
||||
// }
|
||||
// if (key.name == 'right') {
|
||||
// return '<right>'
|
||||
// }
|
||||
if (key.name == 'up') {
|
||||
return '<up>'
|
||||
}
|
||||
if (key.name == 'down') {
|
||||
return '<down>'
|
||||
}
|
||||
return ''
|
||||
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,350 @@
|
|||
:CocAction coc.txt /*:CocAction*
|
||||
:CocCommand coc.txt /*:CocCommand*
|
||||
:CocConfig coc.txt /*:CocConfig*
|
||||
:CocDiagnostics coc.txt /*:CocDiagnostics*
|
||||
:CocDisable coc.txt /*:CocDisable*
|
||||
:CocEnable coc.txt /*:CocEnable*
|
||||
:CocFirst coc.txt /*:CocFirst*
|
||||
:CocFix coc.txt /*:CocFix*
|
||||
:CocInfo coc.txt /*:CocInfo*
|
||||
:CocInstall coc.txt /*:CocInstall*
|
||||
:CocLast coc.txt /*:CocLast*
|
||||
:CocList coc.txt /*:CocList*
|
||||
:CocListCancel coc.txt /*:CocListCancel*
|
||||
:CocListResume coc.txt /*:CocListResume*
|
||||
:CocLocalConfig coc.txt /*:CocLocalConfig*
|
||||
:CocNext coc.txt /*:CocNext*
|
||||
:CocOpenLog coc.txt /*:CocOpenLog*
|
||||
:CocOutline coc.txt /*:CocOutline*
|
||||
:CocPrev coc.txt /*:CocPrev*
|
||||
:CocRebuild coc.txt /*:CocRebuild*
|
||||
:CocRestart coc.txt /*:CocRestart*
|
||||
:CocSearch coc.txt /*:CocSearch*
|
||||
:CocStart coc.txt /*:CocStart*
|
||||
:CocUninstall coc.txt /*:CocUninstall*
|
||||
:CocUpdate coc.txt /*:CocUpdate*
|
||||
:CocUpdateSync coc.txt /*:CocUpdateSync*
|
||||
:CocWatch coc.txt /*:CocWatch*
|
||||
<Plug>(coc-classobj-i) coc.txt /*<Plug>(coc-classobj-i)*
|
||||
<Plug>(coc-cursors-position) coc.txt /*<Plug>(coc-cursors-position)*
|
||||
<Plug>(coc-cursors-word) coc.txt /*<Plug>(coc-cursors-word)*
|
||||
<Plug>(coc-funcobj-a) coc.txt /*<Plug>(coc-funcobj-a)*
|
||||
<plug>(Coc-codeaction-selected) coc.txt /*<plug>(Coc-codeaction-selected)*
|
||||
<plug>(coc-classobj-a) coc.txt /*<plug>(coc-classobj-a)*
|
||||
<plug>(coc-codeaction) coc.txt /*<plug>(coc-codeaction)*
|
||||
<plug>(coc-codeaction-cursor) coc.txt /*<plug>(coc-codeaction-cursor)*
|
||||
<plug>(coc-codeaction-line) coc.txt /*<plug>(coc-codeaction-line)*
|
||||
<plug>(coc-codelens-action) coc.txt /*<plug>(coc-codelens-action)*
|
||||
<plug>(coc-command-repeat) coc.txt /*<plug>(coc-command-repeat)*
|
||||
<plug>(coc-cursors-operator) coc.txt /*<plug>(coc-cursors-operator)*
|
||||
<plug>(coc-cursors-range) coc.txt /*<plug>(coc-cursors-range)*
|
||||
<plug>(coc-declaration) coc.txt /*<plug>(coc-declaration)*
|
||||
<plug>(coc-definition) coc.txt /*<plug>(coc-definition)*
|
||||
<plug>(coc-diagnostic-info) coc.txt /*<plug>(coc-diagnostic-info)*
|
||||
<plug>(coc-diagnostic-next) coc.txt /*<plug>(coc-diagnostic-next)*
|
||||
<plug>(coc-diagnostic-next-error) coc.txt /*<plug>(coc-diagnostic-next-error)*
|
||||
<plug>(coc-diagnostic-prev) coc.txt /*<plug>(coc-diagnostic-prev)*
|
||||
<plug>(coc-diagnostic-prev-error) coc.txt /*<plug>(coc-diagnostic-prev-error)*
|
||||
<plug>(coc-fix-current) coc.txt /*<plug>(coc-fix-current)*
|
||||
<plug>(coc-float-hide) coc.txt /*<plug>(coc-float-hide)*
|
||||
<plug>(coc-float-jump) coc.txt /*<plug>(coc-float-jump)*
|
||||
<plug>(coc-format) coc.txt /*<plug>(coc-format)*
|
||||
<plug>(coc-format-selected) coc.txt /*<plug>(coc-format-selected)*
|
||||
<plug>(coc-funcobj-i) coc.txt /*<plug>(coc-funcobj-i)*
|
||||
<plug>(coc-implementation) coc.txt /*<plug>(coc-implementation)*
|
||||
<plug>(coc-openlink) coc.txt /*<plug>(coc-openlink)*
|
||||
<plug>(coc-range-select) coc.txt /*<plug>(coc-range-select)*
|
||||
<plug>(coc-range-select-backward) coc.txt /*<plug>(coc-range-select-backward)*
|
||||
<plug>(coc-refactor) coc.txt /*<plug>(coc-refactor)*
|
||||
<plug>(coc-references) coc.txt /*<plug>(coc-references)*
|
||||
<plug>(coc-references-used) coc.txt /*<plug>(coc-references-used)*
|
||||
<plug>(coc-rename) coc.txt /*<plug>(coc-rename)*
|
||||
<plug>(coc-type-definition) coc.txt /*<plug>(coc-type-definition)*
|
||||
CocAction('activeExtension') coc.txt /*CocAction('activeExtension')*
|
||||
CocAction('addRanges') coc.txt /*CocAction('addRanges')*
|
||||
CocAction('codeAction') coc.txt /*CocAction('codeAction')*
|
||||
CocAction('codeActionRange') coc.txt /*CocAction('codeActionRange')*
|
||||
CocAction('codeActions') coc.txt /*CocAction('codeActions')*
|
||||
CocAction('codeLensAction') coc.txt /*CocAction('codeLensAction')*
|
||||
CocAction('colorPresentation') coc.txt /*CocAction('colorPresentation')*
|
||||
CocAction('commands') coc.txt /*CocAction('commands')*
|
||||
CocAction('deactivateExtension') coc.txt /*CocAction('deactivateExtension')*
|
||||
CocAction('definitionHover') coc.txt /*CocAction('definitionHover')*
|
||||
CocAction('diagnosticInfo') coc.txt /*CocAction('diagnosticInfo')*
|
||||
CocAction('diagnosticList') coc.txt /*CocAction('diagnosticList')*
|
||||
CocAction('diagnosticPreview') coc.txt /*CocAction('diagnosticPreview')*
|
||||
CocAction('diagnosticRefresh') coc.txt /*CocAction('diagnosticRefresh')*
|
||||
CocAction('diagnosticToggle') coc.txt /*CocAction('diagnosticToggle')*
|
||||
CocAction('diagnosticToggleBuffer') coc.txt /*CocAction('diagnosticToggleBuffer')*
|
||||
CocAction('doCodeAction') coc.txt /*CocAction('doCodeAction')*
|
||||
CocAction('doHover') coc.txt /*CocAction('doHover')*
|
||||
CocAction('doQuickfix') coc.txt /*CocAction('doQuickfix')*
|
||||
CocAction('documentSymbols') coc.txt /*CocAction('documentSymbols')*
|
||||
CocAction('ensureDocument') coc.txt /*CocAction('ensureDocument')*
|
||||
CocAction('extensionStats') coc.txt /*CocAction('extensionStats')*
|
||||
CocAction('fixAll') coc.txt /*CocAction('fixAll')*
|
||||
CocAction('fold') coc.txt /*CocAction('fold')*
|
||||
CocAction('format') coc.txt /*CocAction('format')*
|
||||
CocAction('formatSelected') coc.txt /*CocAction('formatSelected')*
|
||||
CocAction('getCurrentFunctionSymbol') coc.txt /*CocAction('getCurrentFunctionSymbol')*
|
||||
CocAction('getHover') coc.txt /*CocAction('getHover')*
|
||||
CocAction('getWordEdit') coc.txt /*CocAction('getWordEdit')*
|
||||
CocAction('hideOutline') coc.txt /*CocAction('hideOutline')*
|
||||
CocAction('highlight') coc.txt /*CocAction('highlight')*
|
||||
CocAction('incomingCalls') coc.txt /*CocAction('incomingCalls')*
|
||||
CocAction('jumpDeclaration') coc.txt /*CocAction('jumpDeclaration')*
|
||||
CocAction('jumpDefinition') coc.txt /*CocAction('jumpDefinition')*
|
||||
CocAction('jumpImplementation') coc.txt /*CocAction('jumpImplementation')*
|
||||
CocAction('jumpReferences') coc.txt /*CocAction('jumpReferences')*
|
||||
CocAction('jumpTypeDefinition') coc.txt /*CocAction('jumpTypeDefinition')*
|
||||
CocAction('openlink') coc.txt /*CocAction('openlink')*
|
||||
CocAction('organizeImport') coc.txt /*CocAction('organizeImport')*
|
||||
CocAction('outgoingCalls') coc.txt /*CocAction('outgoingCalls')*
|
||||
CocAction('pickColor') coc.txt /*CocAction('pickColor')*
|
||||
CocAction('quickfixes') coc.txt /*CocAction('quickfixes')*
|
||||
CocAction('refactor') coc.txt /*CocAction('refactor')*
|
||||
CocAction('refreshSource') coc.txt /*CocAction('refreshSource')*
|
||||
CocAction('reloadExtension') coc.txt /*CocAction('reloadExtension')*
|
||||
CocAction('rename') coc.txt /*CocAction('rename')*
|
||||
CocAction('resolveWorkspaceSymbol') coc.txt /*CocAction('resolveWorkspaceSymbol')*
|
||||
CocAction('runCommand') coc.txt /*CocAction('runCommand')*
|
||||
CocAction('selectionRanges') coc.txt /*CocAction('selectionRanges')*
|
||||
CocAction('services') coc.txt /*CocAction('services')*
|
||||
CocAction('showIncomingCalls') coc.txt /*CocAction('showIncomingCalls')*
|
||||
CocAction('showOutgoingCalls') coc.txt /*CocAction('showOutgoingCalls')*
|
||||
CocAction('showOutline') coc.txt /*CocAction('showOutline')*
|
||||
CocAction('showSignatureHelp') coc.txt /*CocAction('showSignatureHelp')*
|
||||
CocAction('sourceStat') coc.txt /*CocAction('sourceStat')*
|
||||
CocAction('toggleExtension') coc.txt /*CocAction('toggleExtension')*
|
||||
CocAction('toggleService') coc.txt /*CocAction('toggleService')*
|
||||
CocAction('toggleSource') coc.txt /*CocAction('toggleSource')*
|
||||
CocAction('uninstallExtension') coc.txt /*CocAction('uninstallExtension')*
|
||||
CocAction() coc.txt /*CocAction()*
|
||||
CocAction(getWorkspaceSymbols) coc.txt /*CocAction(getWorkspaceSymbols)*
|
||||
CocActionAsync() coc.txt /*CocActionAsync()*
|
||||
CocBold coc.txt /*CocBold*
|
||||
CocCodeLens coc.txt /*CocCodeLens*
|
||||
CocCursorRange coc.txt /*CocCursorRange*
|
||||
CocDeprecatedHighlight coc.txt /*CocDeprecatedHighlight*
|
||||
CocDiagnosticChange coc.txt /*CocDiagnosticChange*
|
||||
CocErrorFloat coc.txt /*CocErrorFloat*
|
||||
CocErrorHighlight coc.txt /*CocErrorHighlight*
|
||||
CocErrorLine coc.txt /*CocErrorLine*
|
||||
CocErrorSign coc.txt /*CocErrorSign*
|
||||
CocErrorVirtualText coc.txt /*CocErrorVirtualText*
|
||||
CocFadeOut coc.txt /*CocFadeOut*
|
||||
CocFloating coc.txt /*CocFloating*
|
||||
CocHasProvider() coc.txt /*CocHasProvider()*
|
||||
CocHighlightRead coc.txt /*CocHighlightRead*
|
||||
CocHighlightText coc.txt /*CocHighlightText*
|
||||
CocHighlightWrite coc.txt /*CocHighlightWrite*
|
||||
CocHintFloat coc.txt /*CocHintFloat*
|
||||
CocHintHighlight coc.txt /*CocHintHighlight*
|
||||
CocHintLine coc.txt /*CocHintLine*
|
||||
CocHintSign coc.txt /*CocHintSign*
|
||||
CocHintVirtualText coc.txt /*CocHintVirtualText*
|
||||
CocHoverRange coc.txt /*CocHoverRange*
|
||||
CocInfoFloat coc.txt /*CocInfoFloat*
|
||||
CocInfoHighlight coc.txt /*CocInfoHighlight*
|
||||
CocInfoLine coc.txt /*CocInfoLine*
|
||||
CocInfoSign coc.txt /*CocInfoSign*
|
||||
CocInfoVirtualText coc.txt /*CocInfoVirtualText*
|
||||
CocItalic coc.txt /*CocItalic*
|
||||
CocJumpPlaceholder coc.txt /*CocJumpPlaceholder*
|
||||
CocListMode coc.txt /*CocListMode*
|
||||
CocListPath coc.txt /*CocListPath*
|
||||
CocLocations() coc.txt /*CocLocations()*
|
||||
CocLocationsAsync() coc.txt /*CocLocationsAsync()*
|
||||
CocLocationsChange coc.txt /*CocLocationsChange*
|
||||
CocMarkdownCode coc.txt /*CocMarkdownCode*
|
||||
CocMarkdownHeader coc.txt /*CocMarkdownHeader*
|
||||
CocMarkdownLink coc.txt /*CocMarkdownLink*
|
||||
CocMenuSel coc.txt /*CocMenuSel*
|
||||
CocNotify() coc.txt /*CocNotify()*
|
||||
CocNvimInit coc.txt /*CocNvimInit*
|
||||
CocOpenFloat coc.txt /*CocOpenFloat*
|
||||
CocRegistNotification() coc.txt /*CocRegistNotification()*
|
||||
CocRequest() coc.txt /*CocRequest()*
|
||||
CocRequestAsync() coc.txt /*CocRequestAsync()*
|
||||
CocSelectedLine coc.txt /*CocSelectedLine*
|
||||
CocSelectedRange coc.txt /*CocSelectedRange*
|
||||
CocSelectedText coc.txt /*CocSelectedText*
|
||||
CocSem coc.txt /*CocSem*
|
||||
CocStatusChange coc.txt /*CocStatusChange*
|
||||
CocStrikeThrough coc.txt /*CocStrikeThrough*
|
||||
CocSymbol coc.txt /*CocSymbol*
|
||||
CocSymbolArray coc.txt /*CocSymbolArray*
|
||||
CocSymbolBoolean coc.txt /*CocSymbolBoolean*
|
||||
CocSymbolClass coc.txt /*CocSymbolClass*
|
||||
CocSymbolConstant coc.txt /*CocSymbolConstant*
|
||||
CocSymbolConstructor coc.txt /*CocSymbolConstructor*
|
||||
CocSymbolDefault coc.txt /*CocSymbolDefault*
|
||||
CocSymbolEnum coc.txt /*CocSymbolEnum*
|
||||
CocSymbolEnumMember coc.txt /*CocSymbolEnumMember*
|
||||
CocSymbolEvent coc.txt /*CocSymbolEvent*
|
||||
CocSymbolField coc.txt /*CocSymbolField*
|
||||
CocSymbolFile coc.txt /*CocSymbolFile*
|
||||
CocSymbolFunction coc.txt /*CocSymbolFunction*
|
||||
CocSymbolInterface coc.txt /*CocSymbolInterface*
|
||||
CocSymbolKey coc.txt /*CocSymbolKey*
|
||||
CocSymbolMethod coc.txt /*CocSymbolMethod*
|
||||
CocSymbolModule coc.txt /*CocSymbolModule*
|
||||
CocSymbolNamespace coc.txt /*CocSymbolNamespace*
|
||||
CocSymbolNull coc.txt /*CocSymbolNull*
|
||||
CocSymbolNumber coc.txt /*CocSymbolNumber*
|
||||
CocSymbolObject coc.txt /*CocSymbolObject*
|
||||
CocSymbolOperator coc.txt /*CocSymbolOperator*
|
||||
CocSymbolPackage coc.txt /*CocSymbolPackage*
|
||||
CocSymbolProperty coc.txt /*CocSymbolProperty*
|
||||
CocSymbolString coc.txt /*CocSymbolString*
|
||||
CocSymbolStruct coc.txt /*CocSymbolStruct*
|
||||
CocSymbolTypeParameter coc.txt /*CocSymbolTypeParameter*
|
||||
CocSymbolVariable coc.txt /*CocSymbolVariable*
|
||||
CocTagFunc() coc.txt /*CocTagFunc()*
|
||||
CocTerminalOpen coc.txt /*CocTerminalOpen*
|
||||
CocTree coc.txt /*CocTree*
|
||||
CocTreeDescription coc.txt /*CocTreeDescription*
|
||||
CocTreeOpenClose coc.txt /*CocTreeOpenClose*
|
||||
CocTreeSelected coc.txt /*CocTreeSelected*
|
||||
CocTreeTitle coc.txt /*CocTreeTitle*
|
||||
CocUnderline coc.txt /*CocUnderline*
|
||||
CocUnusedHighlight coc.txt /*CocUnusedHighlight*
|
||||
CocWarningFloat coc.txt /*CocWarningFloat*
|
||||
CocWarningHighlight coc.txt /*CocWarningHighlight*
|
||||
CocWarningLine coc.txt /*CocWarningLine*
|
||||
CocWarningSign coc.txt /*CocWarningSign*
|
||||
CocWarningVirtualText coc.txt /*CocWarningVirtualText*
|
||||
b:coc_additional_keywords coc.txt /*b:coc_additional_keywords*
|
||||
b:coc_current_function coc.txt /*b:coc_current_function*
|
||||
b:coc_cursors_activated coc.txt /*b:coc_cursors_activated*
|
||||
b:coc_diagnostic_disable coc.txt /*b:coc_diagnostic_disable*
|
||||
b:coc_diagnostic_info coc.txt /*b:coc_diagnostic_info*
|
||||
b:coc_enabled coc.txt /*b:coc_enabled*
|
||||
b:coc_root_patterns coc.txt /*b:coc_root_patterns*
|
||||
b:coc_suggest_blacklist coc.txt /*b:coc_suggest_blacklist*
|
||||
b:coc_suggest_disable coc.txt /*b:coc_suggest_disable*
|
||||
coc#_select_confirm() coc.txt /*coc#_select_confirm()*
|
||||
coc#add_command() coc.txt /*coc#add_command()*
|
||||
coc#add_extension() coc.txt /*coc#add_extension()*
|
||||
coc#config() coc.txt /*coc#config()*
|
||||
coc#expandable() coc.txt /*coc#expandable()*
|
||||
coc#expandableOrJumpable() coc.txt /*coc#expandableOrJumpable()*
|
||||
coc#float#close() coc.txt /*coc#float#close()*
|
||||
coc#float#close_all() coc.txt /*coc#float#close_all()*
|
||||
coc#float#has_float() coc.txt /*coc#float#has_float()*
|
||||
coc#float#has_scroll() coc.txt /*coc#float#has_scroll()*
|
||||
coc#float#scroll() coc.txt /*coc#float#scroll()*
|
||||
coc#jumpable() coc.txt /*coc#jumpable()*
|
||||
coc#on_enter() coc.txt /*coc#on_enter()*
|
||||
coc#refresh() coc.txt /*coc#refresh()*
|
||||
coc#start() coc.txt /*coc#start()*
|
||||
coc#status() coc.txt /*coc#status()*
|
||||
coc#util#api_version() coc.txt /*coc#util#api_version()*
|
||||
coc#util#extension_root() coc.txt /*coc#util#extension_root()*
|
||||
coc#util#get_config() coc.txt /*coc#util#get_config()*
|
||||
coc#util#get_config_home() coc.txt /*coc#util#get_config_home()*
|
||||
coc#util#get_data_home() coc.txt /*coc#util#get_data_home()*
|
||||
coc#util#job_command() coc.txt /*coc#util#job_command()*
|
||||
coc#util#rebuild() coc.txt /*coc#util#rebuild()*
|
||||
coc#util#root_patterns() coc.txt /*coc#util#root_patterns()*
|
||||
coc-actions coc.txt /*coc-actions*
|
||||
coc-autocmds coc.txt /*coc-autocmds*
|
||||
coc-commands coc.txt /*coc-commands*
|
||||
coc-completion coc.txt /*coc-completion*
|
||||
coc-config-callHierarchy coc.txt /*coc-config-callHierarchy*
|
||||
coc-config-codelens coc.txt /*coc-config-codelens*
|
||||
coc-config-cursors coc.txt /*coc-config-cursors*
|
||||
coc-config-diagnostic coc.txt /*coc-config-diagnostic*
|
||||
coc-config-dialog coc.txt /*coc-config-dialog*
|
||||
coc-config-float coc.txt /*coc-config-float*
|
||||
coc-config-hover coc.txt /*coc-config-hover*
|
||||
coc-config-http coc.txt /*coc-config-http*
|
||||
coc-config-languageserver coc.txt /*coc-config-languageserver*
|
||||
coc-config-list coc.txt /*coc-config-list*
|
||||
coc-config-notification coc.txt /*coc-config-notification*
|
||||
coc-config-npm coc.txt /*coc-config-npm*
|
||||
coc-config-outline coc.txt /*coc-config-outline*
|
||||
coc-config-preferences coc.txt /*coc-config-preferences*
|
||||
coc-config-refactor coc.txt /*coc-config-refactor*
|
||||
coc-config-suggest coc.txt /*coc-config-suggest*
|
||||
coc-config-tree coc.txt /*coc-config-tree*
|
||||
coc-configuration coc.txt /*coc-configuration*
|
||||
coc-contents coc.txt /*coc-contents*
|
||||
coc-custom-source coc.txt /*coc-custom-source*
|
||||
coc-dialog coc.txt /*coc-dialog*
|
||||
coc-dialog-basic coc.txt /*coc-dialog-basic*
|
||||
coc-dialog-confirm coc.txt /*coc-dialog-confirm*
|
||||
coc-dialog-input coc.txt /*coc-dialog-input*
|
||||
coc-dialog-menu coc.txt /*coc-dialog-menu*
|
||||
coc-dialog-picker coc.txt /*coc-dialog-picker*
|
||||
coc-faq coc.txt /*coc-faq*
|
||||
coc-functions coc.txt /*coc-functions*
|
||||
coc-highlights coc.txt /*coc-highlights*
|
||||
coc-installation coc.txt /*coc-installation*
|
||||
coc-interface coc.txt /*coc-interface*
|
||||
coc-introduction coc.txt /*coc-introduction*
|
||||
coc-key-mappings coc.txt /*coc-key-mappings*
|
||||
coc-list coc.txt /*coc-list*
|
||||
coc-list-command coc.txt /*coc-list-command*
|
||||
coc-list-commands coc.txt /*coc-list-commands*
|
||||
coc-list-completion-sources coc.txt /*coc-list-completion-sources*
|
||||
coc-list-configuration coc.txt /*coc-list-configuration*
|
||||
coc-list-context coc.txt /*coc-list-context*
|
||||
coc-list-diagnostics coc.txt /*coc-list-diagnostics*
|
||||
coc-list-extensions coc.txt /*coc-list-extensions*
|
||||
coc-list-links coc.txt /*coc-list-links*
|
||||
coc-list-lists coc.txt /*coc-list-lists*
|
||||
coc-list-location coc.txt /*coc-list-location*
|
||||
coc-list-mappings coc.txt /*coc-list-mappings*
|
||||
coc-list-mappings-custom coc.txt /*coc-list-mappings-custom*
|
||||
coc-list-options coc.txt /*coc-list-options*
|
||||
coc-list-outline coc.txt /*coc-list-outline*
|
||||
coc-list-services coc.txt /*coc-list-services*
|
||||
coc-list-sources coc.txt /*coc-list-sources*
|
||||
coc-list-symbols coc.txt /*coc-list-symbols*
|
||||
coc-list-target coc.txt /*coc-list-target*
|
||||
coc-nvim.txt coc.txt /*coc-nvim.txt*
|
||||
coc-requirements coc.txt /*coc-requirements*
|
||||
coc-status coc.txt /*coc-status*
|
||||
coc-status-airline coc.txt /*coc-status-airline*
|
||||
coc-status-lightline coc.txt /*coc-status-lightline*
|
||||
coc-status-manual coc.txt /*coc-status-manual*
|
||||
coc-tree coc.txt /*coc-tree*
|
||||
coc-tree-filter coc.txt /*coc-tree-filter*
|
||||
coc-tree-mappings coc.txt /*coc-tree-mappings*
|
||||
coc-variables coc.txt /*coc-variables*
|
||||
g:WorkspaceFolders coc.txt /*g:WorkspaceFolders*
|
||||
g:coc_border_joinchars coc.txt /*g:coc_border_joinchars*
|
||||
g:coc_borderchars coc.txt /*g:coc_borderchars*
|
||||
g:coc_channel_timeout coc.txt /*g:coc_channel_timeout*
|
||||
g:coc_config_home coc.txt /*g:coc_config_home*
|
||||
g:coc_data_home coc.txt /*g:coc_data_home*
|
||||
g:coc_disable_startup_warning coc.txt /*g:coc_disable_startup_warning*
|
||||
g:coc_disable_transparent_cursor coc.txt /*g:coc_disable_transparent_cursor*
|
||||
g:coc_disable_uncaught_error coc.txt /*g:coc_disable_uncaught_error*
|
||||
g:coc_enable_locationlist coc.txt /*g:coc_enable_locationlist*
|
||||
g:coc_filetype_map coc.txt /*g:coc_filetype_map*
|
||||
g:coc_global_extensions coc.txt /*g:coc_global_extensions*
|
||||
g:coc_jump_locations coc.txt /*g:coc_jump_locations*
|
||||
g:coc_last_float_win coc.txt /*g:coc_last_float_win*
|
||||
g:coc_last_hover_message coc.txt /*g:coc_last_hover_message*
|
||||
g:coc_markdown_disabled_languages coc.txt /*g:coc_markdown_disabled_languages*
|
||||
g:coc_node_args coc.txt /*g:coc_node_args*
|
||||
g:coc_node_path coc.txt /*g:coc_node_path*
|
||||
g:coc_process_pid coc.txt /*g:coc_process_pid*
|
||||
g:coc_prompt_win_width coc.txt /*g:coc_prompt_win_width*
|
||||
g:coc_quickfix_open_command coc.txt /*g:coc_quickfix_open_command*
|
||||
g:coc_selectmode_mapping coc.txt /*g:coc_selectmode_mapping*
|
||||
g:coc_service_initialized coc.txt /*g:coc_service_initialized*
|
||||
g:coc_snippet_next coc.txt /*g:coc_snippet_next*
|
||||
g:coc_snippet_prev coc.txt /*g:coc_snippet_prev*
|
||||
g:coc_sources_disable_map coc.txt /*g:coc_sources_disable_map*
|
||||
g:coc_start_at_startup coc.txt /*g:coc_start_at_startup*
|
||||
g:coc_status coc.txt /*g:coc_status*
|
||||
g:coc_status_error_sign coc.txt /*g:coc_status_error_sign*
|
||||
g:coc_status_warning_sign coc.txt /*g:coc_status_warning_sign*
|
||||
g:coc_text_prop_offset coc.txt /*g:coc_text_prop_offset*
|
||||
g:coc_uri_prefix_replace_patterns coc.txt /*g:coc_uri_prefix_replace_patterns*
|
||||
g:coc_user_config coc.txt /*g:coc_user_config*
|
||||
g:node_client_debug coc.txt /*g:node_client_debug*
|
||||
http.proxy coc.txt /*http.proxy*
|
|
@ -0,0 +1,8 @@
|
|||
287c743c9f227fdf0e1db452bbb8ae3c5caffc36 branch 'release' of https://github.com/neoclide/coc.nvim
|
||||
a9da141dbcb16e72754269a85c20e14832e81639 not-for-merge branch 'feat/typings-SemanticTokensBuilder' of https://github.com/neoclide/coc.nvim
|
||||
d409bae8d243ea1f364c91fda5e623414fc4aa29 not-for-merge branch 'feat/use-ts-hi-group' of https://github.com/neoclide/coc.nvim
|
||||
d8faa211837900a087e5a37654d225adee7a8cc3 not-for-merge branch 'fix/create-config-file' of https://github.com/neoclide/coc.nvim
|
||||
03c4689f6c86371e570eb3fa1d5fc33726aeeb07 not-for-merge branch 'fix/filetype-detect' of https://github.com/neoclide/coc.nvim
|
||||
6d541365a13ac63bd3674c4987f481301edc2620 not-for-merge branch 'fix/globpath' of https://github.com/neoclide/coc.nvim
|
||||
2901abc80548b8e6aadb2cec48688e52b0aa6104 not-for-merge branch 'fix/typos-schema' of https://github.com/neoclide/coc.nvim
|
||||
19a630de325ed71e153e8ca89f114b040c878b1b not-for-merge branch 'master' of https://github.com/neoclide/coc.nvim
|
|
@ -0,0 +1 @@
|
|||
ref: refs/heads/release
|
|
@ -0,0 +1 @@
|
|||
287c743c9f227fdf0e1db452bbb8ae3c5caffc36
|
|
@ -0,0 +1,14 @@
|
|||
[core]
|
||||
repositoryformatversion = 0
|
||||
filemode = true
|
||||
bare = false
|
||||
logallrefupdates = true
|
||||
[remote "origin"]
|
||||
url = https://github.com/neoclide/coc.nvim.git
|
||||
fetch = +refs/heads/*:refs/remotes/origin/*
|
||||
[branch "master"]
|
||||
remote = origin
|
||||
merge = refs/heads/master
|
||||
[branch "release"]
|
||||
remote = origin
|
||||
merge = refs/heads/release
|
|
@ -0,0 +1 @@
|
|||
Unnamed repository; edit this file 'description' to name the repository.
|
|
@ -0,0 +1,15 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to check the commit log message taken by
|
||||
# applypatch from an e-mail message.
|
||||
#
|
||||
# The hook should exit with non-zero status after issuing an
|
||||
# appropriate message if it wants to stop the commit. The hook is
|
||||
# allowed to edit the commit message file.
|
||||
#
|
||||
# To enable this hook, rename this file to "applypatch-msg".
|
||||
|
||||
. git-sh-setup
|
||||
commitmsg="$(git rev-parse --git-path hooks/commit-msg)"
|
||||
test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"}
|
||||
:
|
|
@ -0,0 +1,24 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to check the commit log message.
|
||||
# Called by "git commit" with one argument, the name of the file
|
||||
# that has the commit message. The hook should exit with non-zero
|
||||
# status after issuing an appropriate message if it wants to stop the
|
||||
# commit. The hook is allowed to edit the commit message file.
|
||||
#
|
||||
# To enable this hook, rename this file to "commit-msg".
|
||||
|
||||
# Uncomment the below to add a Signed-off-by line to the message.
|
||||
# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
|
||||
# hook is more suited to it.
|
||||
#
|
||||
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
|
||||
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
|
||||
|
||||
# This example catches duplicate Signed-off-by lines.
|
||||
|
||||
test "" = "$(grep '^Signed-off-by: ' "$1" |
|
||||
sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || {
|
||||
echo >&2 Duplicate Signed-off-by lines.
|
||||
exit 1
|
||||
}
|
|
@ -0,0 +1,173 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use IPC::Open2;
|
||||
|
||||
# An example hook script to integrate Watchman
|
||||
# (https://facebook.github.io/watchman/) with git to speed up detecting
|
||||
# new and modified files.
|
||||
#
|
||||
# The hook is passed a version (currently 2) and last update token
|
||||
# formatted as a string and outputs to stdout a new update token and
|
||||
# all files that have been modified since the update token. Paths must
|
||||
# be relative to the root of the working tree and separated by a single NUL.
|
||||
#
|
||||
# To enable this hook, rename this file to "query-watchman" and set
|
||||
# 'git config core.fsmonitor .git/hooks/query-watchman'
|
||||
#
|
||||
my ($version, $last_update_token) = @ARGV;
|
||||
|
||||
# Uncomment for debugging
|
||||
# print STDERR "$0 $version $last_update_token\n";
|
||||
|
||||
# Check the hook interface version
|
||||
if ($version ne 2) {
|
||||
die "Unsupported query-fsmonitor hook version '$version'.\n" .
|
||||
"Falling back to scanning...\n";
|
||||
}
|
||||
|
||||
my $git_work_tree = get_working_dir();
|
||||
|
||||
my $retry = 1;
|
||||
|
||||
my $json_pkg;
|
||||
eval {
|
||||
require JSON::XS;
|
||||
$json_pkg = "JSON::XS";
|
||||
1;
|
||||
} or do {
|
||||
require JSON::PP;
|
||||
$json_pkg = "JSON::PP";
|
||||
};
|
||||
|
||||
launch_watchman();
|
||||
|
||||
sub launch_watchman {
|
||||
my $o = watchman_query();
|
||||
if (is_work_tree_watched($o)) {
|
||||
output_result($o->{clock}, @{$o->{files}});
|
||||
}
|
||||
}
|
||||
|
||||
sub output_result {
|
||||
my ($clockid, @files) = @_;
|
||||
|
||||
# Uncomment for debugging watchman output
|
||||
# open (my $fh, ">", ".git/watchman-output.out");
|
||||
# binmode $fh, ":utf8";
|
||||
# print $fh "$clockid\n@files\n";
|
||||
# close $fh;
|
||||
|
||||
binmode STDOUT, ":utf8";
|
||||
print $clockid;
|
||||
print "\0";
|
||||
local $, = "\0";
|
||||
print @files;
|
||||
}
|
||||
|
||||
sub watchman_clock {
|
||||
my $response = qx/watchman clock "$git_work_tree"/;
|
||||
die "Failed to get clock id on '$git_work_tree'.\n" .
|
||||
"Falling back to scanning...\n" if $? != 0;
|
||||
|
||||
return $json_pkg->new->utf8->decode($response);
|
||||
}
|
||||
|
||||
sub watchman_query {
|
||||
my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty')
|
||||
or die "open2() failed: $!\n" .
|
||||
"Falling back to scanning...\n";
|
||||
|
||||
# In the query expression below we're asking for names of files that
|
||||
# changed since $last_update_token but not from the .git folder.
|
||||
#
|
||||
# To accomplish this, we're using the "since" generator to use the
|
||||
# recency index to select candidate nodes and "fields" to limit the
|
||||
# output to file names only. Then we're using the "expression" term to
|
||||
# further constrain the results.
|
||||
if (substr($last_update_token, 0, 1) eq "c") {
|
||||
$last_update_token = "\"$last_update_token\"";
|
||||
}
|
||||
my $query = <<" END";
|
||||
["query", "$git_work_tree", {
|
||||
"since": $last_update_token,
|
||||
"fields": ["name"],
|
||||
"expression": ["not", ["dirname", ".git"]]
|
||||
}]
|
||||
END
|
||||
|
||||
# Uncomment for debugging the watchman query
|
||||
# open (my $fh, ">", ".git/watchman-query.json");
|
||||
# print $fh $query;
|
||||
# close $fh;
|
||||
|
||||
print CHLD_IN $query;
|
||||
close CHLD_IN;
|
||||
my $response = do {local $/; <CHLD_OUT>};
|
||||
|
||||
# Uncomment for debugging the watch response
|
||||
# open ($fh, ">", ".git/watchman-response.json");
|
||||
# print $fh $response;
|
||||
# close $fh;
|
||||
|
||||
die "Watchman: command returned no output.\n" .
|
||||
"Falling back to scanning...\n" if $response eq "";
|
||||
die "Watchman: command returned invalid output: $response\n" .
|
||||
"Falling back to scanning...\n" unless $response =~ /^\{/;
|
||||
|
||||
return $json_pkg->new->utf8->decode($response);
|
||||
}
|
||||
|
||||
sub is_work_tree_watched {
|
||||
my ($output) = @_;
|
||||
my $error = $output->{error};
|
||||
if ($retry > 0 and $error and $error =~ m/unable to resolve root .* directory (.*) is not watched/) {
|
||||
$retry--;
|
||||
my $response = qx/watchman watch "$git_work_tree"/;
|
||||
die "Failed to make watchman watch '$git_work_tree'.\n" .
|
||||
"Falling back to scanning...\n" if $? != 0;
|
||||
$output = $json_pkg->new->utf8->decode($response);
|
||||
$error = $output->{error};
|
||||
die "Watchman: $error.\n" .
|
||||
"Falling back to scanning...\n" if $error;
|
||||
|
||||
# Uncomment for debugging watchman output
|
||||
# open (my $fh, ">", ".git/watchman-output.out");
|
||||
# close $fh;
|
||||
|
||||
# Watchman will always return all files on the first query so
|
||||
# return the fast "everything is dirty" flag to git and do the
|
||||
# Watchman query just to get it over with now so we won't pay
|
||||
# the cost in git to look up each individual file.
|
||||
my $o = watchman_clock();
|
||||
$error = $output->{error};
|
||||
|
||||
die "Watchman: $error.\n" .
|
||||
"Falling back to scanning...\n" if $error;
|
||||
|
||||
output_result($o->{clock}, ("/"));
|
||||
$last_update_token = $o->{clock};
|
||||
|
||||
eval { launch_watchman() };
|
||||
return 0;
|
||||
}
|
||||
|
||||
die "Watchman: $error.\n" .
|
||||
"Falling back to scanning...\n" if $error;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub get_working_dir {
|
||||
my $working_dir;
|
||||
if ($^O =~ 'msys' || $^O =~ 'cygwin') {
|
||||
$working_dir = Win32::GetCwd();
|
||||
$working_dir =~ tr/\\/\//;
|
||||
} else {
|
||||
require Cwd;
|
||||
$working_dir = Cwd::cwd();
|
||||
}
|
||||
|
||||
return $working_dir;
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to prepare a packed repository for use over
|
||||
# dumb transports.
|
||||
#
|
||||
# To enable this hook, rename this file to "post-update".
|
||||
|
||||
exec git update-server-info
|
|
@ -0,0 +1,14 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to verify what is about to be committed
|
||||
# by applypatch from an e-mail message.
|
||||
#
|
||||
# The hook should exit with non-zero status after issuing an
|
||||
# appropriate message if it wants to stop the commit.
|
||||
#
|
||||
# To enable this hook, rename this file to "pre-applypatch".
|
||||
|
||||
. git-sh-setup
|
||||
precommit="$(git rev-parse --git-path hooks/pre-commit)"
|
||||
test -x "$precommit" && exec "$precommit" ${1+"$@"}
|
||||
:
|
|
@ -0,0 +1,49 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to verify what is about to be committed.
|
||||
# Called by "git commit" with no arguments. The hook should
|
||||
# exit with non-zero status after issuing an appropriate message if
|
||||
# it wants to stop the commit.
|
||||
#
|
||||
# To enable this hook, rename this file to "pre-commit".
|
||||
|
||||
if git rev-parse --verify HEAD >/dev/null 2>&1
|
||||
then
|
||||
against=HEAD
|
||||
else
|
||||
# Initial commit: diff against an empty tree object
|
||||
against=$(git hash-object -t tree /dev/null)
|
||||
fi
|
||||
|
||||
# If you want to allow non-ASCII filenames set this variable to true.
|
||||
allownonascii=$(git config --type=bool hooks.allownonascii)
|
||||
|
||||
# Redirect output to stderr.
|
||||
exec 1>&2
|
||||
|
||||
# Cross platform projects tend to avoid non-ASCII filenames; prevent
|
||||
# them from being added to the repository. We exploit the fact that the
|
||||
# printable range starts at the space character and ends with tilde.
|
||||
if [ "$allownonascii" != "true" ] &&
|
||||
# Note that the use of brackets around a tr range is ok here, (it's
|
||||
# even required, for portability to Solaris 10's /usr/bin/tr), since
|
||||
# the square bracket bytes happen to fall in the designated range.
|
||||
test $(git diff --cached --name-only --diff-filter=A -z $against |
|
||||
LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
|
||||
then
|
||||
cat <<\EOF
|
||||
Error: Attempt to add a non-ASCII file name.
|
||||
|
||||
This can cause problems if you want to work with people on other platforms.
|
||||
|
||||
To be portable it is advisable to rename the file.
|
||||
|
||||
If you know what you are doing you can disable this check using:
|
||||
|
||||
git config hooks.allownonascii true
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# If there are whitespace errors, print the offending file names and fail.
|
||||
exec git diff-index --check --cached $against --
|
|
@ -0,0 +1,13 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to verify what is about to be committed.
|
||||
# Called by "git merge" with no arguments. The hook should
|
||||
# exit with non-zero status after issuing an appropriate message to
|
||||
# stderr if it wants to stop the merge commit.
|
||||
#
|
||||
# To enable this hook, rename this file to "pre-merge-commit".
|
||||
|
||||
. git-sh-setup
|
||||
test -x "$GIT_DIR/hooks/pre-commit" &&
|
||||
exec "$GIT_DIR/hooks/pre-commit"
|
||||
:
|
|
@ -0,0 +1,53 @@
|
|||
#!/bin/sh
|
||||
|
||||
# An example hook script to verify what is about to be pushed. Called by "git
|
||||
# push" after it has checked the remote status, but before anything has been
|
||||
# pushed. If this script exits with a non-zero status nothing will be pushed.
|
||||
#
|
||||
# This hook is called with the following parameters:
|
||||
#
|
||||
# $1 -- Name of the remote to which the push is being done
|
||||
# $2 -- URL to which the push is being done
|
||||
#
|
||||
# If pushing without using a named remote those arguments will be equal.
|
||||
#
|
||||
# Information about the commits which are being pushed is supplied as lines to
|
||||
# the standard input in the form:
|
||||
#
|
||||
# <local ref> <local oid> <remote ref> <remote oid>
|
||||
#
|
||||
# This sample shows how to prevent push of commits where the log message starts
|
||||
# with "WIP" (work in progress).
|
||||
|
||||
remote="$1"
|
||||
url="$2"
|
||||
|
||||
zero=$(git hash-object --stdin </dev/null | tr '[0-9a-f]' '0')
|
||||
|
||||
while read local_ref local_oid remote_ref remote_oid
|
||||
do
|
||||
if test "$local_oid" = "$zero"
|
||||
then
|
||||
# Handle delete
|
||||
:
|
||||
else
|
||||
if test "$remote_oid" = "$zero"
|
||||
then
|
||||
# New branch, examine all commits
|
||||
range="$local_oid"
|
||||
else
|
||||
# Update to existing branch, examine new commits
|
||||
range="$remote_oid..$local_oid"
|
||||
fi
|
||||
|
||||
# Check for WIP commit
|
||||
commit=$(git rev-list -n 1 --grep '^WIP' "$range")
|
||||
if test -n "$commit"
|
||||
then
|
||||
echo >&2 "Found WIP commit in $local_ref, not pushing"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
exit 0
|
|
@ -0,0 +1,169 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2006, 2008 Junio C Hamano
|
||||
#
|
||||
# The "pre-rebase" hook is run just before "git rebase" starts doing
|
||||
# its job, and can prevent the command from running by exiting with
|
||||
# non-zero status.
|
||||
#
|
||||
# The hook is called with the following parameters:
|
||||
#
|
||||
# $1 -- the upstream the series was forked from.
|
||||
# $2 -- the branch being rebased (or empty when rebasing the current branch).
|
||||
#
|
||||
# This sample shows how to prevent topic branches that are already
|
||||
# merged to 'next' branch from getting rebased, because allowing it
|
||||
# would result in rebasing already published history.
|
||||
|
||||
publish=next
|
||||
basebranch="$1"
|
||||
if test "$#" = 2
|
||||
then
|
||||
topic="refs/heads/$2"
|
||||
else
|
||||
topic=`git symbolic-ref HEAD` ||
|
||||
exit 0 ;# we do not interrupt rebasing detached HEAD
|
||||
fi
|
||||
|
||||
case "$topic" in
|
||||
refs/heads/??/*)
|
||||
;;
|
||||
*)
|
||||
exit 0 ;# we do not interrupt others.
|
||||
;;
|
||||
esac
|
||||
|
||||
# Now we are dealing with a topic branch being rebased
|
||||
# on top of master. Is it OK to rebase it?
|
||||
|
||||
# Does the topic really exist?
|
||||
git show-ref -q "$topic" || {
|
||||
echo >&2 "No such branch $topic"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Is topic fully merged to master?
|
||||
not_in_master=`git rev-list --pretty=oneline ^master "$topic"`
|
||||
if test -z "$not_in_master"
|
||||
then
|
||||
echo >&2 "$topic is fully merged to master; better remove it."
|
||||
exit 1 ;# we could allow it, but there is no point.
|
||||
fi
|
||||
|
||||
# Is topic ever merged to next? If so you should not be rebasing it.
|
||||
only_next_1=`git rev-list ^master "^$topic" ${publish} | sort`
|
||||
only_next_2=`git rev-list ^master ${publish} | sort`
|
||||
if test "$only_next_1" = "$only_next_2"
|
||||
then
|
||||
not_in_topic=`git rev-list "^$topic" master`
|
||||
if test -z "$not_in_topic"
|
||||
then
|
||||
echo >&2 "$topic is already up to date with master"
|
||||
exit 1 ;# we could allow it, but there is no point.
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
else
|
||||
not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"`
|
||||
/usr/bin/perl -e '
|
||||
my $topic = $ARGV[0];
|
||||
my $msg = "* $topic has commits already merged to public branch:\n";
|
||||
my (%not_in_next) = map {
|
||||
/^([0-9a-f]+) /;
|
||||
($1 => 1);
|
||||
} split(/\n/, $ARGV[1]);
|
||||
for my $elem (map {
|
||||
/^([0-9a-f]+) (.*)$/;
|
||||
[$1 => $2];
|
||||
} split(/\n/, $ARGV[2])) {
|
||||
if (!exists $not_in_next{$elem->[0]}) {
|
||||
if ($msg) {
|
||||
print STDERR $msg;
|
||||
undef $msg;
|
||||
}
|
||||
print STDERR " $elem->[1]\n";
|
||||
}
|
||||
}
|
||||
' "$topic" "$not_in_next" "$not_in_master"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
<<\DOC_END
|
||||
|
||||
This sample hook safeguards topic branches that have been
|
||||
published from being rewound.
|
||||
|
||||
The workflow assumed here is:
|
||||
|
||||
* Once a topic branch forks from "master", "master" is never
|
||||
merged into it again (either directly or indirectly).
|
||||
|
||||
* Once a topic branch is fully cooked and merged into "master",
|
||||
it is deleted. If you need to build on top of it to correct
|
||||
earlier mistakes, a new topic branch is created by forking at
|
||||
the tip of the "master". This is not strictly necessary, but
|
||||
it makes it easier to keep your history simple.
|
||||
|
||||
* Whenever you need to test or publish your changes to topic
|
||||
branches, merge them into "next" branch.
|
||||
|
||||
The script, being an example, hardcodes the publish branch name
|
||||
to be "next", but it is trivial to make it configurable via
|
||||
$GIT_DIR/config mechanism.
|
||||
|
||||
With this workflow, you would want to know:
|
||||
|
||||
(1) ... if a topic branch has ever been merged to "next". Young
|
||||
topic branches can have stupid mistakes you would rather
|
||||
clean up before publishing, and things that have not been
|
||||
merged into other branches can be easily rebased without
|
||||
affecting other people. But once it is published, you would
|
||||
not want to rewind it.
|
||||
|
||||
(2) ... if a topic branch has been fully merged to "master".
|
||||
Then you can delete it. More importantly, you should not
|
||||
build on top of it -- other people may already want to
|
||||
change things related to the topic as patches against your
|
||||
"master", so if you need further changes, it is better to
|
||||
fork the topic (perhaps with the same name) afresh from the
|
||||
tip of "master".
|
||||
|
||||
Let's look at this example:
|
||||
|
||||
o---o---o---o---o---o---o---o---o---o "next"
|
||||
/ / / /
|
||||
/ a---a---b A / /
|
||||
/ / / /
|
||||
/ / c---c---c---c B /
|
||||
/ / / \ /
|
||||
/ / / b---b C \ /
|
||||
/ / / / \ /
|
||||
---o---o---o---o---o---o---o---o---o---o---o "master"
|
||||
|
||||
|
||||
A, B and C are topic branches.
|
||||
|
||||
* A has one fix since it was merged up to "next".
|
||||
|
||||
* B has finished. It has been fully merged up to "master" and "next",
|
||||
and is ready to be deleted.
|
||||
|
||||
* C has not merged to "next" at all.
|
||||
|
||||
We would want to allow C to be rebased, refuse A, and encourage
|
||||
B to be deleted.
|
||||
|
||||
To compute (1):
|
||||
|
||||
git rev-list ^master ^topic next
|
||||
git rev-list ^master next
|
||||
|
||||
if these match, topic has not merged in next at all.
|
||||
|
||||
To compute (2):
|
||||
|
||||
git rev-list master..topic
|
||||
|
||||
if this is empty, it is fully merged to "master".
|
||||
|
||||
DOC_END
|
|
@ -0,0 +1,24 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to make use of push options.
|
||||
# The example simply echoes all push options that start with 'echoback='
|
||||
# and rejects all pushes when the "reject" push option is used.
|
||||
#
|
||||
# To enable this hook, rename this file to "pre-receive".
|
||||
|
||||
if test -n "$GIT_PUSH_OPTION_COUNT"
|
||||
then
|
||||
i=0
|
||||
while test "$i" -lt "$GIT_PUSH_OPTION_COUNT"
|
||||
do
|
||||
eval "value=\$GIT_PUSH_OPTION_$i"
|
||||
case "$value" in
|
||||
echoback=*)
|
||||
echo "echo from the pre-receive-hook: ${value#*=}" >&2
|
||||
;;
|
||||
reject)
|
||||
exit 1
|
||||
esac
|
||||
i=$((i + 1))
|
||||
done
|
||||
fi
|
|
@ -0,0 +1,42 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to prepare the commit log message.
|
||||
# Called by "git commit" with the name of the file that has the
|
||||
# commit message, followed by the description of the commit
|
||||
# message's source. The hook's purpose is to edit the commit
|
||||
# message file. If the hook fails with a non-zero status,
|
||||
# the commit is aborted.
|
||||
#
|
||||
# To enable this hook, rename this file to "prepare-commit-msg".
|
||||
|
||||
# This hook includes three examples. The first one removes the
|
||||
# "# Please enter the commit message..." help message.
|
||||
#
|
||||
# The second includes the output of "git diff --name-status -r"
|
||||
# into the message, just before the "git status" output. It is
|
||||
# commented because it doesn't cope with --amend or with squashed
|
||||
# commits.
|
||||
#
|
||||
# The third example adds a Signed-off-by line to the message, that can
|
||||
# still be edited. This is rarely a good idea.
|
||||
|
||||
COMMIT_MSG_FILE=$1
|
||||
COMMIT_SOURCE=$2
|
||||
SHA1=$3
|
||||
|
||||
/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE"
|
||||
|
||||
# case "$COMMIT_SOURCE,$SHA1" in
|
||||
# ,|template,)
|
||||
# /usr/bin/perl -i.bak -pe '
|
||||
# print "\n" . `git diff --cached --name-status -r`
|
||||
# if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;;
|
||||
# *) ;;
|
||||
# esac
|
||||
|
||||
# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
|
||||
# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE"
|
||||
# if test -z "$COMMIT_SOURCE"
|
||||
# then
|
||||
# /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE"
|
||||
# fi
|
|
@ -0,0 +1,78 @@
|
|||
#!/bin/sh
|
||||
|
||||
# An example hook script to update a checked-out tree on a git push.
|
||||
#
|
||||
# This hook is invoked by git-receive-pack(1) when it reacts to git
|
||||
# push and updates reference(s) in its repository, and when the push
|
||||
# tries to update the branch that is currently checked out and the
|
||||
# receive.denyCurrentBranch configuration variable is set to
|
||||
# updateInstead.
|
||||
#
|
||||
# By default, such a push is refused if the working tree and the index
|
||||
# of the remote repository has any difference from the currently
|
||||
# checked out commit; when both the working tree and the index match
|
||||
# the current commit, they are updated to match the newly pushed tip
|
||||
# of the branch. This hook is to be used to override the default
|
||||
# behaviour; however the code below reimplements the default behaviour
|
||||
# as a starting point for convenient modification.
|
||||
#
|
||||
# The hook receives the commit with which the tip of the current
|
||||
# branch is going to be updated:
|
||||
commit=$1
|
||||
|
||||
# It can exit with a non-zero status to refuse the push (when it does
|
||||
# so, it must not modify the index or the working tree).
|
||||
die () {
|
||||
echo >&2 "$*"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Or it can make any necessary changes to the working tree and to the
|
||||
# index to bring them to the desired state when the tip of the current
|
||||
# branch is updated to the new commit, and exit with a zero status.
|
||||
#
|
||||
# For example, the hook can simply run git read-tree -u -m HEAD "$1"
|
||||
# in order to emulate git fetch that is run in the reverse direction
|
||||
# with git push, as the two-tree form of git read-tree -u -m is
|
||||
# essentially the same as git switch or git checkout that switches
|
||||
# branches while keeping the local changes in the working tree that do
|
||||
# not interfere with the difference between the branches.
|
||||
|
||||
# The below is a more-or-less exact translation to shell of the C code
|
||||
# for the default behaviour for git's push-to-checkout hook defined in
|
||||
# the push_to_deploy() function in builtin/receive-pack.c.
|
||||
#
|
||||
# Note that the hook will be executed from the repository directory,
|
||||
# not from the working tree, so if you want to perform operations on
|
||||
# the working tree, you will have to adapt your code accordingly, e.g.
|
||||
# by adding "cd .." or using relative paths.
|
||||
|
||||
if ! git update-index -q --ignore-submodules --refresh
|
||||
then
|
||||
die "Up-to-date check failed"
|
||||
fi
|
||||
|
||||
if ! git diff-files --quiet --ignore-submodules --
|
||||
then
|
||||
die "Working directory has unstaged changes"
|
||||
fi
|
||||
|
||||
# This is a rough translation of:
|
||||
#
|
||||
# head_has_history() ? "HEAD" : EMPTY_TREE_SHA1_HEX
|
||||
if git cat-file -e HEAD 2>/dev/null
|
||||
then
|
||||
head=HEAD
|
||||
else
|
||||
head=$(git hash-object -t tree --stdin </dev/null)
|
||||
fi
|
||||
|
||||
if ! git diff-index --quiet --cached --ignore-submodules $head --
|
||||
then
|
||||
die "Working directory has staged changes"
|
||||
fi
|
||||
|
||||
if ! git read-tree -u -m "$commit"
|
||||
then
|
||||
die "Could not update working tree to new HEAD"
|
||||
fi
|
|
@ -0,0 +1,128 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to block unannotated tags from entering.
|
||||
# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
|
||||
#
|
||||
# To enable this hook, rename this file to "update".
|
||||
#
|
||||
# Config
|
||||
# ------
|
||||
# hooks.allowunannotated
|
||||
# This boolean sets whether unannotated tags will be allowed into the
|
||||
# repository. By default they won't be.
|
||||
# hooks.allowdeletetag
|
||||
# This boolean sets whether deleting tags will be allowed in the
|
||||
# repository. By default they won't be.
|
||||
# hooks.allowmodifytag
|
||||
# This boolean sets whether a tag may be modified after creation. By default
|
||||
# it won't be.
|
||||
# hooks.allowdeletebranch
|
||||
# This boolean sets whether deleting branches will be allowed in the
|
||||
# repository. By default they won't be.
|
||||
# hooks.denycreatebranch
|
||||
# This boolean sets whether remotely creating branches will be denied
|
||||
# in the repository. By default this is allowed.
|
||||
#
|
||||
|
||||
# --- Command line
|
||||
refname="$1"
|
||||
oldrev="$2"
|
||||
newrev="$3"
|
||||
|
||||
# --- Safety check
|
||||
if [ -z "$GIT_DIR" ]; then
|
||||
echo "Don't run this script from the command line." >&2
|
||||
echo " (if you want, you could supply GIT_DIR then run" >&2
|
||||
echo " $0 <ref> <oldrev> <newrev>)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
|
||||
echo "usage: $0 <ref> <oldrev> <newrev>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- Config
|
||||
allowunannotated=$(git config --type=bool hooks.allowunannotated)
|
||||
allowdeletebranch=$(git config --type=bool hooks.allowdeletebranch)
|
||||
denycreatebranch=$(git config --type=bool hooks.denycreatebranch)
|
||||
allowdeletetag=$(git config --type=bool hooks.allowdeletetag)
|
||||
allowmodifytag=$(git config --type=bool hooks.allowmodifytag)
|
||||
|
||||
# check for no description
|
||||
projectdesc=$(sed -e '1q' "$GIT_DIR/description")
|
||||
case "$projectdesc" in
|
||||
"Unnamed repository"* | "")
|
||||
echo "*** Project description file hasn't been set" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# --- Check types
|
||||
# if $newrev is 0000...0000, it's a commit to delete a ref.
|
||||
zero=$(git hash-object --stdin </dev/null | tr '[0-9a-f]' '0')
|
||||
if [ "$newrev" = "$zero" ]; then
|
||||
newrev_type=delete
|
||||
else
|
||||
newrev_type=$(git cat-file -t $newrev)
|
||||
fi
|
||||
|
||||
case "$refname","$newrev_type" in
|
||||
refs/tags/*,commit)
|
||||
# un-annotated tag
|
||||
short_refname=${refname##refs/tags/}
|
||||
if [ "$allowunannotated" != "true" ]; then
|
||||
echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2
|
||||
echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
refs/tags/*,delete)
|
||||
# delete tag
|
||||
if [ "$allowdeletetag" != "true" ]; then
|
||||
echo "*** Deleting a tag is not allowed in this repository" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
refs/tags/*,tag)
|
||||
# annotated tag
|
||||
if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1
|
||||
then
|
||||
echo "*** Tag '$refname' already exists." >&2
|
||||
echo "*** Modifying a tag is not allowed in this repository." >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
refs/heads/*,commit)
|
||||
# branch
|
||||
if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then
|
||||
echo "*** Creating a branch is not allowed in this repository" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
refs/heads/*,delete)
|
||||
# delete branch
|
||||
if [ "$allowdeletebranch" != "true" ]; then
|
||||
echo "*** Deleting a branch is not allowed in this repository" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
refs/remotes/*,commit)
|
||||
# tracking branch
|
||||
;;
|
||||
refs/remotes/*,delete)
|
||||
# delete tracking branch
|
||||
if [ "$allowdeletebranch" != "true" ]; then
|
||||
echo "*** Deleting a tracking branch is not allowed in this repository" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
# Anything else (is there anything else?)
|
||||
echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# --- Finished
|
||||
exit 0
|
Binary file not shown.
|
@ -0,0 +1,6 @@
|
|||
# git ls-files --others --exclude-from=.git/info/exclude
|
||||
# Lines that start with '#' are comments.
|
||||
# For a project mostly in C, the following would be a good set of
|
||||
# exclude patterns (uncomment them if you want to use them):
|
||||
# *.[oa]
|
||||
# *~
|
|
@ -0,0 +1,7 @@
|
|||
0000000000000000000000000000000000000000 03c9add7cd867a013102dcb45fb4e75304d227d7 linux <linux@archlinux.localdomain> 1632171242 -0400 clone: from https://github.com/neoclide/coc.nvim.git
|
||||
03c9add7cd867a013102dcb45fb4e75304d227d7 287c743c9f227fdf0e1db452bbb8ae3c5caffc36 linux <linux@archlinux.localdomain> 1632171242 -0400 checkout: moving from master to release
|
||||
287c743c9f227fdf0e1db452bbb8ae3c5caffc36 287c743c9f227fdf0e1db452bbb8ae3c5caffc36 array-in-a-matrix <nova.neutrino@protonmail.com> 1634528024 -0400 checkout: moving from release to release
|
||||
287c743c9f227fdf0e1db452bbb8ae3c5caffc36 287c743c9f227fdf0e1db452bbb8ae3c5caffc36 array-in-a-matrix <nova.neutrino@protonmail.com> 1634528044 -0400 checkout: moving from release to release
|
||||
287c743c9f227fdf0e1db452bbb8ae3c5caffc36 287c743c9f227fdf0e1db452bbb8ae3c5caffc36 linux <linux@archlinux.localdomain> 1636403107 -0500 checkout: moving from release to release
|
||||
287c743c9f227fdf0e1db452bbb8ae3c5caffc36 287c743c9f227fdf0e1db452bbb8ae3c5caffc36 linux <linux@archlinux.localdomain> 1636786427 -0500 checkout: moving from release to release
|
||||
287c743c9f227fdf0e1db452bbb8ae3c5caffc36 287c743c9f227fdf0e1db452bbb8ae3c5caffc36 linux <linux@archlinux.localdomain> 1636786624 -0500 checkout: moving from release to release
|
|
@ -0,0 +1 @@
|
|||
0000000000000000000000000000000000000000 03c9add7cd867a013102dcb45fb4e75304d227d7 linux <linux@archlinux.localdomain> 1632171242 -0400 clone: from https://github.com/neoclide/coc.nvim.git
|
|
@ -0,0 +1 @@
|
|||
0000000000000000000000000000000000000000 287c743c9f227fdf0e1db452bbb8ae3c5caffc36 linux <linux@archlinux.localdomain> 1632171242 -0400 branch: Created from refs/remotes/origin/release
|
|
@ -0,0 +1 @@
|
|||
0000000000000000000000000000000000000000 03c9add7cd867a013102dcb45fb4e75304d227d7 linux <linux@archlinux.localdomain> 1632171242 -0400 clone: from https://github.com/neoclide/coc.nvim.git
|
|
@ -0,0 +1 @@
|
|||
5c8569bb4d20903c7767644037b5e9566b844ced d409bae8d243ea1f364c91fda5e623414fc4aa29 linux <linux@archlinux.localdomain> 1636403107 -0500 fetch --progress: forced-update
|
|
@ -0,0 +1 @@
|
|||
0000000000000000000000000000000000000000 03c4689f6c86371e570eb3fa1d5fc33726aeeb07 linux <linux@archlinux.localdomain> 1636403107 -0500 fetch --progress: storing head
|
|
@ -0,0 +1 @@
|
|||
0000000000000000000000000000000000000000 6d541365a13ac63bd3674c4987f481301edc2620 linux <linux@archlinux.localdomain> 1636403107 -0500 fetch --progress: storing head
|
|
@ -0,0 +1 @@
|
|||
0000000000000000000000000000000000000000 2901abc80548b8e6aadb2cec48688e52b0aa6104 linux <linux@archlinux.localdomain> 1636403107 -0500 fetch --progress: storing head
|
|
@ -0,0 +1,3 @@
|
|||
03c9add7cd867a013102dcb45fb4e75304d227d7 80012b82bca3e1491408dfe7bf0911774d1555c5 array-in-a-matrix <nova.neutrino@protonmail.com> 1634528024 -0400 fetch --progress: fast-forward
|
||||
80012b82bca3e1491408dfe7bf0911774d1555c5 9f6e29b6f9661ebba10ff3df84de11d96c8a9e56 linux <linux@archlinux.localdomain> 1636403107 -0500 fetch --progress: fast-forward
|
||||
9f6e29b6f9661ebba10ff3df84de11d96c8a9e56 19a630de325ed71e153e8ca89f114b040c878b1b linux <linux@archlinux.localdomain> 1636786427 -0500 fetch --progress: fast-forward
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,164 @@
|
|||
# pack-refs with: peeled fully-peeled sorted
|
||||
a9da141dbcb16e72754269a85c20e14832e81639 refs/remotes/origin/feat/typings-SemanticTokensBuilder
|
||||
5c8569bb4d20903c7767644037b5e9566b844ced refs/remotes/origin/feat/use-ts-hi-group
|
||||
d8faa211837900a087e5a37654d225adee7a8cc3 refs/remotes/origin/fix/create-config-file
|
||||
03c9add7cd867a013102dcb45fb4e75304d227d7 refs/remotes/origin/master
|
||||
287c743c9f227fdf0e1db452bbb8ae3c5caffc36 refs/remotes/origin/release
|
||||
f04dc51c6ec7b94bd4c69d309261872e937df414 refs/tags/v0.0.1
|
||||
^22b92e27d5b49e33cd447e6d3e78f5105644e45b
|
||||
dbb91163451b3d49e3a890123b2c2fedc08a5b71 refs/tags/v0.0.10
|
||||
^8fc87b49d98c129ef8ac361dd8f7a585c1a4610e
|
||||
ac3e875abc499d477ef082e3d7b195f64da2ebc8 refs/tags/v0.0.11
|
||||
^26c61ae7351ae82434d4ab8e7428ae1ea013a3da
|
||||
78e5b95768bf7abd229d31bbf010f31eaf690141 refs/tags/v0.0.12
|
||||
^beb9bbaf53e731aa35655864f2a67d804fd19151
|
||||
18b96cd70dc51abe94a342761645f1aa52c1c0f2 refs/tags/v0.0.13
|
||||
^956373fc765ef7170bb0486b39543f8871bc49ba
|
||||
77c9c882d883ba94a9c2afb14a5159d74e3a5f8a refs/tags/v0.0.14
|
||||
^fbe0c0ba5a347d8c15645c1de220cb46b07451c6
|
||||
4b9cecf2cbc9339baac934bd8388292965d4025f refs/tags/v0.0.15
|
||||
^ea30ddd9d84bb0a8f1a0493dbbbbab89f40c1360
|
||||
b38d9d1d156c1c43aad28a4320e409f66c7c37ec refs/tags/v0.0.16
|
||||
^03afb5a5ee3c5b6019165de21bd258bb25608966
|
||||
8689f4e500fa5f2ccf1ee79ef152867548aa2e94 refs/tags/v0.0.17
|
||||
^793f383eebf3bd7494612647d5874ee17dbd3f34
|
||||
6728d3c52d55f1c628dadfcb5d1c731ba834a8d0 refs/tags/v0.0.18
|
||||
^09ab945bffee37f18044ad35a8b16de3b028d9f8
|
||||
4ab50af897330613ec231ad5910b7bb68c8dd631 refs/tags/v0.0.19
|
||||
^7fcbd2f2884d849d202c1f4fdfbb484eab662d9b
|
||||
0b6ef2692c9c8d25c0fc025be519a3838c1360d4 refs/tags/v0.0.2
|
||||
^6ff769957caa30a8406b081d33d517de93e062b7
|
||||
da60344da81230d606a894debdc1a3148de4d307 refs/tags/v0.0.20
|
||||
^631a15712b584e2bab7785b4eb77b607a4ccf6ad
|
||||
c5ca3063d0299b62c07bd19f2db7278637c52a16 refs/tags/v0.0.21
|
||||
^2c388b7570c1bf656cb172b5d58f3ee598c3206e
|
||||
7f9888ece8d96549183c8f55e6b808e31cae7564 refs/tags/v0.0.22
|
||||
^332e3dab1b565e655b59d610a9c8af792c6bd402
|
||||
ff7f1d21b33849ecd2edf9fec7783c109dac75f2 refs/tags/v0.0.23
|
||||
^69693d5a67563e206ebdd3b86892828333eaacf8
|
||||
c663a491409346291cce776fdf6a8e36cda78446 refs/tags/v0.0.24
|
||||
^4eab01fd64ab0833341233e0f668a22b2b1d630a
|
||||
6e342249be39a00bfc7e6af275ea2d3aca8580c6 refs/tags/v0.0.25
|
||||
^4302b8c4b31c0058f282ea82a981079f8fb0c6f1
|
||||
f9e51efe089a6860b14a34d7bc61f12b8fa6e708 refs/tags/v0.0.26
|
||||
^a531abd8d388bcfd4dd3e74fea657b1c73a8e2ba
|
||||
acb825d9ae78708260647a20e80d0af5acc043b1 refs/tags/v0.0.27
|
||||
^cfc5de3af5677b1807b1689946ec032b5a3d74fb
|
||||
741427096aa90832ccee8643e3075de8dc3a1403 refs/tags/v0.0.28
|
||||
^17e840426bcbd08eafa835ed3755bfbef0041766
|
||||
028470fe9d8b36bd8fa098639acaa32f390f77b6 refs/tags/v0.0.29
|
||||
^d090fe35ba7a41f28afbeb7af48ef2ea4793bdd6
|
||||
6dfd03d1e235727e542a598b55c1c1abed45360b refs/tags/v0.0.3
|
||||
^bf55a14df878b8beb27e58e4b7d791ef6cfc7ad6
|
||||
5bc7a6b73566fc51eabc38a1d3a1b03a33b61e75 refs/tags/v0.0.30
|
||||
^cce7b97ac7f9bb7b79d80ae190c5d94370759250
|
||||
400b95d41c0ad718dcf257c20266727c0bf8258b refs/tags/v0.0.31
|
||||
^389b061290ba28ff415c22f0111a717b5a8d658c
|
||||
a885e47304d1c8d59ba53a66392303230f9d2361 refs/tags/v0.0.32
|
||||
^a2e1ce587ef7785a2f8837ecd271fee3bd534463
|
||||
bfda8e212117089cd847c589926de321e7e86b6f refs/tags/v0.0.33
|
||||
^d0400c4d3eac8f3c09f47a54157702d0e152ca38
|
||||
e28bc3ed716e17f2ca0bf0b28b049403a9f54b47 refs/tags/v0.0.34
|
||||
^abc90a8546003f066a12506e6b845f29aade10aa
|
||||
dca9eedc871bfa28c77d1c3aa1ec276a50a8337f refs/tags/v0.0.35
|
||||
^822831326d13a35cfb8f3e39766878bb19ef9ba9
|
||||
3d2a66fb479fe869df0dfccfd9c15754b0acebff refs/tags/v0.0.36
|
||||
^413e0c621109145abdec310815a45fc8ca5b7ab3
|
||||
70935de626fbf94efdbad904f221be3a586e52cb refs/tags/v0.0.37
|
||||
^853325fc6deba3739768e412c0051189df40f2c5
|
||||
ddd4e73034c3ff257546438c4b5797a9122fbf1a refs/tags/v0.0.38
|
||||
^4a9ddf7818b7335397694123bf7e3c8520b6157b
|
||||
ed872b6f29566ef151e7848df192bcd810e3246b refs/tags/v0.0.39
|
||||
^7bfc761508e83fa7c9b71e21803d87c71bcd7303
|
||||
3f483ba0053eae8a8b2d10c1ac1d0166538e3cab refs/tags/v0.0.4
|
||||
^0006071c02be4825947d4d204a194c11a4d51339
|
||||
6657ac490b22ba480351d773338540d8c9c9b561 refs/tags/v0.0.40
|
||||
^ab3d5bb636b283eed4230b6de67f5c0060ba2c99
|
||||
c63b9ede6e8c58b1a07501b39b7f52bc83ebb72f refs/tags/v0.0.41
|
||||
^f6213c07d27c09ae641ca12b675993f36d9ef245
|
||||
a07572a395c157a6b375499ddb1a06bf9c4c8b73 refs/tags/v0.0.42
|
||||
^77ce9449cc48c67f26b61a9983a92dca05efa4c3
|
||||
4cc4eb6681cbed19071e173eed7cea823ed0b9f4 refs/tags/v0.0.43
|
||||
^3cde2877fc081ddaa2c33771c7ff1c48b28e3757
|
||||
0205f69b2f88192ff9f6d26ba553e7f8dd204333 refs/tags/v0.0.44
|
||||
^36142bfbcd7830842741481524cd2199086fe9ed
|
||||
7efd2aa105390e4425ab59c4551f5603130eaf47 refs/tags/v0.0.45
|
||||
^81a898f86fd2de10b819fc7d1232c0ebdc789f17
|
||||
66b8f38b24e5ffeba217dc30f8e82c3365bc3581 refs/tags/v0.0.46
|
||||
^0b964d8e53ea7b195ed6bf3690868597da1fcf30
|
||||
471cba59e14ff83faa0355d55feccf02cd68bcc2 refs/tags/v0.0.47
|
||||
^3a2c77577af7a2a87249095eb9b21ae288eb9ad6
|
||||
1f6bb8a5d9e078d17db46c8801014d152af7de08 refs/tags/v0.0.48
|
||||
^7e22262a35ab7f88a766163da8a2c45047d7d492
|
||||
4758fc8a6faa7a02b19ba7061cc9a0ed58a476f3 refs/tags/v0.0.49
|
||||
^137f1e5ebe127c0b3fa9737ef1bfb9b998a7b936
|
||||
06dc4ebecacc2e811c7e7227b6defa0dca7b883e refs/tags/v0.0.5
|
||||
^f79d99f96b609d22422316aade582d89ec4040ac
|
||||
cff78d9bcde15e78c19c570060a775ac8bc767e2 refs/tags/v0.0.50
|
||||
^c764e78653f2a16cf79c3a96c8dde1cef474d1cc
|
||||
3dc13b9ef6e42c2c2808b165a761a7ee219c5421 refs/tags/v0.0.51
|
||||
^cc96ec2ae3105637b360b359bc1d6f9952b954eb
|
||||
e265598fe7dbfbe4a057d2d9ac52362569c47561 refs/tags/v0.0.52
|
||||
^a4f5c8b00fdeb10c3749a56683dc64b020ee1f4f
|
||||
5f9c14126d9d2595abbfc826a6f5f770d1440d1b refs/tags/v0.0.53
|
||||
^ec1afd6ff1aee4e3d4decf0783f4c1b150c0b6d4
|
||||
ef91d772500e667dc24ad86facf80279defc06c7 refs/tags/v0.0.54
|
||||
^18bf65dd7a8cd60ff4104308d5394f8cf2a3c263
|
||||
ff195f7fec41d04d6455f975b7ec9161219c40f4 refs/tags/v0.0.55
|
||||
^2a367a85c4fe32d9dd9edc90b28dd6eea6008c7a
|
||||
0174bf62b5d3964c1c95969a69a7e570e8e6066c refs/tags/v0.0.56
|
||||
^a41122142a706886bb7f4a15f8b264691ea803a6
|
||||
166f0453763e8eab0d9b7a89f9caf0a0e8426c63 refs/tags/v0.0.57
|
||||
fa79c9dbc91a7dd48bcf20fc22932ee84dc0d888 refs/tags/v0.0.58
|
||||
d0138b596a98504075e8e501e413726a60039c47 refs/tags/v0.0.59
|
||||
^7ad16b1cfcaca1a374f4f860bfd30f61d01f1a94
|
||||
c58c164e6066dfff2b5595287af6e0ec2e30fc52 refs/tags/v0.0.6
|
||||
^521dce04581fa28f1815f2910ba8620607e5b29a
|
||||
8e686aaabfadea22e99d0999c20f846587518eb4 refs/tags/v0.0.60
|
||||
^87bd430d1fd6c666803599d5a5d2ac5f298a1b27
|
||||
8c3515a64d1b62281c151b5d3758fdce40889d2b refs/tags/v0.0.61
|
||||
^739bcaa607218343ab0c975d630d7ddb4395ed34
|
||||
9a9b0fe72c03a8bf8309d01b234bdc412ad66433 refs/tags/v0.0.62
|
||||
^f22fc67289232f6f5ebe43ff4a880a3075eaa9b9
|
||||
d322272d4efa14c7a893816ead32d69fa40c1a5b refs/tags/v0.0.63
|
||||
^b4a00e70ac676578f42c4378adc11a5ff7496805
|
||||
467ae709ff5731e850b024e2839d5bfb83c97f95 refs/tags/v0.0.64
|
||||
^81ab35e88023ec56e4e031aff9a53e855f09615c
|
||||
610f0273ef253ac9fa3dbd84a1eadbddced0eeaf refs/tags/v0.0.65
|
||||
^f7874ec7d7f8d2c72a603d10c40915c74ca2dcaa
|
||||
55d10a1a74d38cc95ed423f9f6e8cd2e83a953c0 refs/tags/v0.0.66
|
||||
^f9652d2f59d665a91b8c7fad299bc81a81e957a9
|
||||
5d4d7901aa2cef84d5aa9ce2a813dfddc1d332ee refs/tags/v0.0.67
|
||||
^8741e930c9c5cef97befd3e6f256b121aebe15b3
|
||||
6bfe462eafecd0d5863e0e56644e28760cbbbd0a refs/tags/v0.0.68
|
||||
^a0ab9a09d08e28169954be07327ab13907541d6f
|
||||
3bb539522d08c140c75343b669f5a21cdadcc7b0 refs/tags/v0.0.69
|
||||
^ea70c2a428d23922a75d59fa6ba1014cbc9b556e
|
||||
d53854344d5527c13453fd980768693e3b6f5165 refs/tags/v0.0.7
|
||||
^4ac8dcefe15550e0c9beba4bf414eee85e510dc5
|
||||
4c94035b279d00357077096921333ac31a88b1ed refs/tags/v0.0.70
|
||||
^99537d3c524e567ec343a01ffd2bd0aaf9605a4b
|
||||
aa292e6a5c8c9d93aa6cd64edb69d14ace740f0c refs/tags/v0.0.71
|
||||
^fa429d0bbcc0eca6ff85fc9a4d55e43406beec19
|
||||
3a6e4290021487dca233ac920f31432b24346a25 refs/tags/v0.0.72
|
||||
^22daa03a7d7b7c14125c0d4f5c11ff80e3d70606
|
||||
a14804a77d9343b924c85846c92050328bf22d0f refs/tags/v0.0.73
|
||||
^d9f01a6023da4f2186291d32f6a1bf71b47309e6
|
||||
b9022bf188fd185bca80b7042b9237e866992924 refs/tags/v0.0.74
|
||||
^9edc0edaa180fa6e8d5834f8ffc2e9a1f01e1a73
|
||||
522d4fcd2b20775716a37056e3c650b2900d422d refs/tags/v0.0.75
|
||||
^5b392c532585e3f88e1a143d7f969a992843e908
|
||||
0c953758c729c088fe0112f1b88fd8ca7032fce7 refs/tags/v0.0.76
|
||||
^a362bc4352ad986f4e8eacd2ec0b8e2d6895ce77
|
||||
008095e129a0516de03c89b87c5a33c984fdf919 refs/tags/v0.0.77
|
||||
^149c37453982ed83f98fbd73820d8d0f72f23cf0
|
||||
048a909ffe0253039bca94e26dc1d140204919c0 refs/tags/v0.0.78
|
||||
^705f94fdd3e9919b6f3c69e4dd44bf3bb5167f60
|
||||
f545756ad2cc5f4f58c96006ee49846a5ee07f1d refs/tags/v0.0.79
|
||||
^6242534f300920296ca27bbecd9d13a0aebbcdbe
|
||||
6e7ff454aa9f15db16813b8d3961ee185d897b27 refs/tags/v0.0.8
|
||||
^3535df0dbc3ecb81dd2a5912e303b7a8bceaa9d4
|
||||
edcba0e3f573707081f73669790073183e643148 refs/tags/v0.0.80
|
||||
^ce448a6945d90609bc5c063577e12b859de0834b
|
||||
e75b3e3bf054b50611f222076a46947585baed84 refs/tags/v0.0.9
|
||||
^afd3d356b09837b5036bd098387f13fa26057128
|
|
@ -0,0 +1 @@
|
|||
03c9add7cd867a013102dcb45fb4e75304d227d7
|
|
@ -0,0 +1 @@
|
|||
287c743c9f227fdf0e1db452bbb8ae3c5caffc36
|
|
@ -0,0 +1 @@
|
|||
ref: refs/remotes/origin/master
|
|
@ -0,0 +1 @@
|
|||
d409bae8d243ea1f364c91fda5e623414fc4aa29
|
|
@ -0,0 +1 @@
|
|||
03c4689f6c86371e570eb3fa1d5fc33726aeeb07
|
|
@ -0,0 +1 @@
|
|||
6d541365a13ac63bd3674c4987f481301edc2620
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue