remove note plugin

This commit is contained in:
Julien Rabier 2020-05-30 20:51:11 +02:00
parent 0457406122
commit 0c00431eb4
9 changed files with 2 additions and 790 deletions

View File

@ -1,6 +1,8 @@
deploy_dotfiles.sh
.config/**/.git
.config/**/.git/**
.config/**/notational-fzf-vim
.config/**/notational-fzf-vim/**
{{ if eq .chezmoi.hostname "taupo" }}
.bin
.bin/bat

View File

@ -1,70 +0,0 @@
## 2.1.0
Added more window size management with `g:nv_window_width` and
`g:nv_window_direction`. Can now run fullscreen with `:NV!`.
## 2.0.0
- Rename `g:nv_directories` to `g:nv_search_paths`. This emphasizes
that you can search directories *and* files.
- Use `shellescape` instead of `fnameescape` to avoid path issues.
- Fix bug in search that would cause it to ignore 1-line long files.
## 1.1.0
- Color filenames and line numbers.
## 1.0.0
- [rg](https://github.com/BurntSushi/ripgrep) is now required. `ag`
will no longer work.
- The preview feature has been reworked. Now, the preview window will
show several lines of context around the currently selected line.
## 0.8.0
- New default for preview window that sensibly sets width. Most users
should not need to set this anymore.
- Short pathname display no longer shows `./` before filename if it's
in the current working directory.
## 0.7.0
- You can now restrict your search with arguments passed to `:NV`
- Fixed a bug that made preview window too narrow
## 0.6.0
- Improve path shortening to display (in decreasing order of
priority):
- `.`
- `..`
- `~`
- Python 3 is now required for the path shortening script to work.
- Key mappings to open files are now customizable.
- set `highlight` to use `truecolor` if available and Solarized Dark
background.
## 0.5.0
- `g:nv_preview_width` is now a percentage. This makes it more useful
on small screens, but slightly less useful on large ones without
some config.
## 0.4.0
- Add support for files in `g:nv_directories`
## 0.3.0
- Add (working) short pathnames feature
## 0.2.0
- Updated README to include use cases and to be easier to read.
## 0.1.0
- Added
[`highlight`](http://www.andre-simon.de/doku/highlight/en/highlight.html)
as (superior) alternative to `coderay`

View File

@ -1,291 +0,0 @@
# Notational FZF
***Loosen the mental blockages to recording information. Scrape away the
tartar of convention that handicaps its retrieval.***
--- [Notational Velocity home page](http://notational.net/)
Notational Velocity is a note-taking app where searching for a note and
creating one are the same operation.
You search for a query, and if no note matches, it creates a new note
with that query as the title.
## Usage
See the following GIF or watch this
[asciinema](https://asciinema.org/a/oXAsE6lDnywkrSSH5xuOIVQuO):
![Usage](/screenshots/usage.gif?raw=true "Usage")
## Installation
``` {.vim}
" with vim-plug
Plug 'https://github.com/alok/notational-fzf-vim'
```
## Changes
Read `CHANGELOG.md`.
## Description
Vim is great for writing. But it isn't optimized for note-taking, where
you often create lots of little notes and frequently change larger notes
in a separate directory from the one you're working in. For years I used
[nvALT](http://brettterpstra.com/projects/nvalt/) and whenever I had to
do serious editing, I would open the file in Vim.
But some things about nvALT bugged me.
- It's not meant for large text files, and opening them will cause it
to lag *a lot*.
- I can't use splits
- I do most of my work in Vim, so why have another window open,
wasting precious screen space with its inferior editing
capabilities. Sorry Brett, but nvALT can't match Vim's editing
speed.
- I also disagree with some parts of Notational Velocity's philosophy.
Plugins like [vim-pad](https://github.com/fmoralesc/vim-pad) didn't do
it for me either, because:
- I don't want to archive my notes. I should be able to just search
for them.
- I don't want to use the first line as the title since I have notes
with duplicated titles in different directories, like `README.md`.
- I just want to be able to search a set of directories and create
notes in one of them, ***quickly***.
When [Junegunn](https://github.com/junegunn/) created
[`fzf`](https://github.com/junegunn/fzf), I realized that I could have
all that, in Vim.
This plugin allows you to define a list of directories that you want to
search. The first directory in the list is used as the main directory,
unless you set `g:nv_main_directory`. If you press `control-x` after
typing some words, it will use those words as the filename to create a
file in the main directory. It will then open that file in a vertical
split. If that file already exists, don't worry, it won't overwrite it.
This plugin never modifies your files at any point. It can only read,
open, and create them.
You can define relative links, so adding `./docs` and `./notes` will
work. Keep in mind that it's relative to your current working directory
(as Vim interprets it).
## Dependencies
- [`rg`](https://github.com/BurntSushi/ripgrep) is required for its
fast search.
- [`fzf`](https://github.com/junegunn/fzf).
- `fzf` Vim plugin. Install the Vim plugin that comes with `fzf`,
which can be done like so if you use
[vim-plug](https://github.com/junegunn/vim-plug).
``` {.vim}
Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' }
```
- Python 3.5 or higher, for the preview window and filepath
shortening.
## Optional dependencies
- Pypy 3, for a potential speedup
## Required Settings
You have to define a list of directories **or** files (which all must be
strings) to search. This setting is named `g:nv_search_paths`.
Remember that these can be relative links.
``` {.vim}
" example
let g:nv_search_paths = ['~/wiki', '~/writing', '~/code', 'docs.md' , './notes.md']
```
## Detailed Usage
This plugin unites searching and file creation. It defines a single
command `:NV`, which can take 0 or more arguments, which are interpreted
as regexes.
Type `:NV` or bind it to a mapping to bring up a fuzzy search menu. Type
in your search terms and it will fuzzy search for them. Adding an
exclamation mark to the command (`:NV!`), will run it fullscreen.
You can type `:NV` to see all results, and then filter them with FZF.
You can type `:NV python` to restrict your initial search to lines that
contain the phrase `python`. `:NV [0-9] [0-9]` will find all numbers
separated by a space. You know, regexes.
It does not search in a fully fuzzy fashion because that's less useful
for prose. It looks for full words, but they don't have to be next to
each other, just on the same line. You can use the arrow keys or `c-p`
and `c-n` to scroll through the search results, and then hit one of
these keys to open up a file:
Note that the following options can be customized.
- `c-x`: Use search string as filename and open in vertical split.
- `c-v`: Open in vertical split
- `c-s`: Open in horizontal split
- `c-t`: Open in new tab
- `c-y`: Yank the selected filenames
- `<Enter>`: Open highlighted search result in current buffer
The lines around the selected file will be visible in a preview window.
## Mappings
This plugin only defines a command `:NV`, and if you want a mapping for
it, you can define it yourself. This is intentionally not done by
default. You should use whatever mapping(s) work best for you.
For example,
``` {.vim}
nnoremap <silent> <c-s> :NV<CR>
```
## Optional Settings and Their Defaults
You can display the full path by setting `g:nv_use_short_pathnames = 0`.
You can toggle displaying the preview window by pressing `alt-p`. This
is handy on smaller screens. If you don't want to show the preview by
default, set `g:nv_show_preview = 0`.
``` {.vim}
" String. Set to '' (the empty string) if you don't want an extension appended by default.
" Don't forget the dot, unless you don't want one.
let g:nv_default_extension = '.md'
" String. Default is first directory found in `g:nv_search_paths`. Error thrown
"if no directory found and g:nv_main_directory is not specified
"let g:nv_main_directory = g:nv_main_directory or (first directory in g:nv_search_paths)
" Dictionary with string keys and values. Must be in the form 'ctrl-KEY':
" 'command' or 'alt-KEY' : 'command'. See examples below.
let g:nv_keymap = {
\ 'ctrl-s': 'split ',
\ 'ctrl-v': 'vertical split ',
\ 'ctrl-t': 'tabedit ',
\ })
" String. Must be in the form 'ctrl-KEY' or 'alt-KEY'
let g:nv_create_note_key = 'ctrl-x'
" String. Controls how new note window is created.
let g:nv_create_note_window = 'vertical split'
" Boolean. Show preview. Set by default. Pressing Alt-p in FZF will toggle this for the current search.
let g:nv_show_preview = 1
" Boolean. Respect .*ignore files in or above nv_search_paths. Set by default.
let g:nv_use_ignore_files = 1
" Boolean. Include hidden files and folders in search. Disabled by default.
let g:nv_include_hidden = 0
" Boolean. Wrap text in preview window.
let g:nv_wrap_preview_text = 1
" String. Width of window as a percentage of screen's width.
let g:nv_window_width = '40%'
" String. Determines where the window is. Valid options are: 'right', 'left', 'up', 'down'.
let g:nv_window_direction = 'down'
" String. Command to open the window (e.g. `vertical` `aboveleft` `30new` `call my_function()`).
let g:nv_window_command = 'call my_function()'
" Float. Width of preview window as a percentage of screen's width. 50% by default.
let g:nv_preview_width = 50
" String. Determines where the preview window is. Valid options are: 'right', 'left', 'up', 'down'.
let g:nv_preview_direction = 'right'
" String. Yanks the selected filenames to the default register.
let g:nv_yank_key = 'ctrl-y'
" String. Separator used between yanked filenames.
let g:nv_yank_separator = "\n"
" Boolean. If set, will truncate each path element to a single character. If
" you have colons in your pathname, this will fail. Set by default.
let g:nv_use_short_pathnames = 1
"List of Strings. Shell glob patterns. Ignore all filenames that match any of
" the patterns.
let g:nv_ignore_pattern = ['summarize-*', 'misc*']
" List of Strings. Key mappings like above in case you want to define your own
" handler function. Most users won't want to set this to anything.
let g:nv_expect_keys = []
```
You can also define your own handler function, in case you don't like
how this plugin handles input but like how it wraps everything else. It
*must* be called `NV_note_handler`.
## Potential Use Cases
- Add `~/notes` and `~/wiki` so your notes are only one key binding
away.
- Add relative links like `./notes`, `./doc`, etc. to
`g:nv_search_paths` so you can always see/update the documentation
of your current project and keep up-to-date personal notes.
## Philosophy
To quote [scrod](https://github.com/scrod/nv/issues/22),
> The reasoning behind Notational Velocity's present lack of
> multi-database support is that storing notes in separate databases
> would 1) Require the same kinds of decisions that
> category/folder-based organizers force upon their users (e.g., "Is
> this note going to be work-specific or home-specific?"), and 2) Defeat
> the point of instantaneous searching by requiring, ultimately, the
> user to repeat each search for every database in use.
- By providing a default directory, we offer (one) fix to the first
issue.
- By searching the whole set of directories simultaneously, we handle
the second.
It also handles Notational Velocity's issue with multiple databases.
UNIX does not allow repeated filenames in the same folder, but often the
parent folder provides context, like in `workout/TODO.md` and
`coding/TODO.md`.
This plug-in attempts to abstract the operation of note-taking over
*all* the notes you take, with priority given to one main notes
directory.
## Caveat Emptor
- This plugin is just a wrapper over FZF that can view directories and
open/create files. That's all it's ever meant to be. Anything else
would be put into a separate plugin.
## Feedback
Is ***always*** welcome. If you have any ideas or issues, let me know
and I'll try to address them. Not all will be implemented, but if they
fit into the philosophy of this plugin or seem really useful, I'll do my
best.
## License
Apache 2

View File

@ -1,12 +0,0 @@
## Checklist
<!-- Update to the latest version of this plugin *first*. -->
- [ ] I updated.
<!-- If your issue is about changing how notes are handled once selected, search for `NV_note_handler` in `README.md`-->
- [ ] `NV_note_handler` cannot fix my issue.
## Summary of Problem

View File

@ -1,4 +0,0 @@
notes.md
tags.lock
usage.frames.json
tags.temp

View File

@ -1,33 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Colorize the current line in the preview window in bold red."""
import os
import os.path as path
import shutil
import sys
line = int(sys.argv[1])
file = sys.argv[2]
# Use a large default for width since the extra doesn't get displayed anyway
width = max(1, shutil.get_terminal_size().lines // 2)
end_width = 200
# file numbers start at 1
beginning = max(1, line - width)
end = line + end_width
# ANSI escape sequences for coloring matched line
RED = "\033[1;31m"
RESET = "\033[0;0m"
BOLD = "\033[;1m"
if __name__ == "__main__":
with open(path.normpath(file)) as f:
for linenum, line_content in enumerate(f, start=1):
if beginning <= linenum <= end:
if linenum == line:
print(BOLD + RED + line_content.rstrip() + RESET)
else:
print(line_content.rstrip())

View File

@ -1,117 +0,0 @@
#!/usr/bin/env pypy3
# encoding: utf-8
# Supposedly, importing so that you don't need dots in names speeds up a
# script, and the point of this one is to run fast.
import platform
from os import pardir
from os.path import abspath, expanduser, join, sep, split, splitdrive
from pathlib import PurePath
from sys import stdin
# These are floated to the top so they aren't recalculated every loop. The
# most restrictive replacements should come earlier.
REPLACEMENTS = ("", pardir, "~")
old_paths = [abspath(expanduser(replacement)) for replacement in REPLACEMENTS]
IS_WINDOWS = platform.system().lower() == "windows"
def prettyprint_path(path: str, old_path: str, replacement: str) -> str:
# Pretty print the path prefix
path = path.replace(old_path, replacement, 1)
# Truncate the rest of the path to a single character.
short_path = join(replacement, *[x[0] for x in PurePath(path).parts[1:]])
return short_path
def shorten(path: str):
"""Returns 2 strings, the shortened parent directory and the filename."""
# We don't want to shorten the filename, just its parent directory, so we
# `split()` and just shorten `path`.
path, filename = split(path)
# use empty replacement for current directory. it expands correctly
for replacement, old_path in zip(REPLACEMENTS, old_paths):
if path.startswith(old_path):
short_path = prettyprint_path(path, old_path, replacement)
# to avoid multiple replacements
break
# If no replacement was found, shorten the entire path.
else:
short_path = join(*[x[0] for x in PurePath(path).parts])
return short_path, filename
GREEN = "\033[32m"
PURPLE = "\033[35m" # looks pink to me
CYAN = "\033[36m"
RESET = "\033[0m"
# RED = '\033[31m'
# BLUE = '\033[34m'
# LIGHTRED = '\033[91m'
# YELLOW = '\033[93m'
# LIGHTBLUE = '\033[94m'
# LIGHTCYAN = '\033[96m'
def color(line, color):
return color + line + RESET
def process_line(line: str) -> str:
# Expected format is colon separated `name:line number:contents`
if IS_WINDOWS:
# Windows paths may contain a colon, e.g. C:\Windows\ which messes up the split
# splitdrive(string) results in the following:
# Windows drive letter, e.g. C:\Windows\Folder\Foo.txt -> ('C', '\Windows\Folder\Foo.txt')
# Windows UNC path, e.g. \\Server\Share\Folder\Foo.txt -> ('\\Server\Share', '\Folder\Foo.txt')
# *nix, e.g. /any/path/to/file.txt -> ('', '/any/path/to/file.txt')
_, line = splitdrive(line) # Toss the drive letter since it's not necessary.
filename, linenum, contents = line.split(sep=":", maxsplit=2)
# Drop trailing newline.
contents = contents.rstrip()
# Normalize path for further processing.
if not IS_WINDOWS:
# This prepends cwd in Windows which is unnecessary.
filename = abspath(filename)
shortened_parent, basename = shorten(filename)
# The conditional is to avoid a leading slash if the parent is replaced
# with an empty directory. The slash is manually colored because otherwise
# `os.path.join` won't do it.
if shortened_parent:
colored_short_name = color(shortened_parent + sep, PURPLE) + color(
basename, CYAN
)
else:
colored_short_name = color(basename, CYAN)
# Format is: long form, line number, short form, line number, rest of line. This is so Vim can process it.
formatted_line = ":".join(
[
color(filename, CYAN),
color(linenum, GREEN),
colored_short_name,
color(linenum, GREEN),
contents,
]
)
return formatted_line
# We print the long and short forms, and one form is picked in the Vim script that uses this.
# print(formatted_line)
if __name__ == "__main__":
for line in stdin:
print(process_line(line))

View File

@ -1,263 +0,0 @@
"============================== Utility functions =============================
" XXX: fnameescape vs. shellescape: for vim's consumption vs. the shell's
" consumption
function! s:single_quote(str)
return "'" . a:str . "'"
endfunction
"============================= Dependencies ================================
if !executable('rg')
echoerr '`rg` is not installed. See https://github.com/BurntSushi/ripgrep for installation instructions.'
finish
endif
"============================== User settings ==============================
if !exists('g:nv_search_paths')
if exists('g:nv_directories')
echoerr '`g:nv_directories` has been renamed `g:nv_search_paths`. Please update your config files.'
else
echoerr '`g:nv_search_paths` is not defined.'
endif
finish
endif
let s:window_direction = get(g:, 'nv_window_direction', 'down')
let s:window_width = get(g:, 'nv_window_width', '40%')
let s:window_command = get(g:, 'nv_window_command', '')
let s:ext = get(g:, 'nv_default_extension', '.md')
" Valid options are ['up', 'down', 'right', 'left']. Default is 'right'. No colon for
" this command since it's first in the list.
let s:preview_direction = get(g:, 'nv_preview_direction', 'right')
let s:wrap_text = get(g:, 'nv_wrap_preview_text', 0) ? 'wrap' : ''
" Show preview unless user set it to be hidden
let s:show_preview = get(g:, 'nv_show_preview', 1) ? '' : 'hidden'
" Respect .*ignore files unless user has chosen not to
let s:use_ignore_files = get(g:, 'nv_use_ignore_files', 1) ? '' : '--no-ignore'
" Skip hidden files and folders unless user chooses to include them
let s:include_hidden = get(g:, 'nv_include_hidden', 0) ? '--hidden' : ''
" How wide to make preview window. 72 characters is default.
let s:preview_width = exists('g:nv_preview_width') ? string(float2nr(str2float(g:nv_preview_width) / 100.0 * &columns)) : ''
" Expand all directories and escape metacharacters to avoid issues later.
let s:search_paths = map(copy(g:nv_search_paths), 'expand(v:val)')
" Separator for yanked files
let s:yank_separator = get(g:, 'nv_yank_separator', "\n")
"=========================== Windows Overrides ============================
if has('win64') || has('win32')
let s:null_path = 'NUL'
let s:command = ''
else
let s:null_path = '/dev/null'
let s:command = 'command'
endif
" The `exists()` check needs to be first in case the main directory is not
" part of `g:nv_search_paths`.
if exists('g:nv_main_directory')
let s:main_dir = g:nv_main_directory
else
for path in s:search_paths
if isdirectory(path)
let s:main_dir = path
break
endif
endfor
" this awkward bit of code is to get around the lack of a for-else
" loop in vim
if !exists('s:main_dir')
echomsg 'no directories found in `g:nv_search_paths`'
finish
endif
endif
let s:search_path_str = join(map(copy(s:search_paths), 'shellescape(v:val)'))
"=========================== Keymap ========================================
let s:create_note_key = get(g:, 'nv_create_note_key', 'ctrl-x')
let s:yank_key = get(g:, 'nv_yank_key', 'ctrl-y')
let s:create_note_window = get(g:, 'nv_create_note_window', 'vertical split ')
let s:keymap = get(g:, 'nv_keymap',
\ {'ctrl-s': 'split',
\ 'ctrl-v': 'vertical split',
\ 'ctrl-t': 'tabedit',
\ })
" Use `extend` in case user overrides default keys
let s:keymap = extend(s:keymap, {
\ s:create_note_key : s:create_note_window,
\ })
" FZF expects a comma separated string.
let s:expect_keys = join(keys(s:keymap) + get(g:, 'nv_expect_keys', []) + [s:yank_key], ',')
"================================ Yank string ==============================
function! s:yank_to_register(data)
let @" = a:data
silent! let @* = a:data
silent! let @+ = a:data
endfunction
"================================ Short Pathnames ==========================
let s:use_short_pathnames = get(g:, 'nv_use_short_pathnames', 1)
" Python 3 is required for this to work
let s:python_executable = executable('pypy3') ? 'pypy3' : get(g:, 'python3_host_prog', 'python3')
let s:highlight_path_expr = join([s:python_executable , '-S',expand('<sfile>:p:h:h') . '/print_lines.py' , '{2} {1} ', '2>' . s:null_path,])
if s:use_short_pathnames
let s:format_path_expr = join([' | ', s:python_executable, '-S', shellescape(expand('<sfile>:p:h:h') . '/shorten_path_for_notational_fzf.py'),])
" After piping through the Python script, our format is
" filename:linum:shortname:linenum:contents, so we start at index 3 to
" avoid displaying the long pathname
" We skip index 4 to avoid showing line numbers
let s:display_start_index = '3,5..'
else
let s:format_path_expr = ''
" Since we don't pipe through the python script, our data format is
" filename:linenum:contents, so we start at 1.
let s:display_start_index = '1..'
endif
"============================ Ignore patterns ==============================
function! s:ignore_list_to_str(pattern)
"list -> space separated string of glob patterns.
" Format to ignore a pattern.
" XXX The leading space matters.
let l:glob_fmt = ' --glob !'
return l:glob_fmt . join(map(copy(a:pattern), 's:single_quote(v:val)'), l:glob_fmt) " prepend glob format string so the first pattern is ignored too.
endfunction
let s:nv_ignore_pattern = exists('g:nv_ignore_pattern') ? s:ignore_list_to_str(g:nv_ignore_pattern) : ''
"============================== Handler Function ===========================
function! s:handler(lines) abort
" exit if empty
if a:lines == [] || a:lines == ['','','']
return
endif
" Expect at least 2 elements, `query` and `keypress`, which may be empty
" strings.
let query = a:lines[0]
let keypress = a:lines[1]
" `edit` is fallback in case something goes wrong
let cmd = get(s:keymap, keypress, 'edit')
" Preprocess candidates here. expect lines to have fmt
" filename:linenum:content
" Handle creating note.
if keypress ==? s:create_note_key
let candidates = [fnameescape(s:main_dir . '/' . query . s:ext)]
elseif keypress ==? s:yank_key
let pat = '\v(.{-}):\d+:'
let hashes = join(filter(map(copy(a:lines[2:]), 'matchlist(v:val, pat)[1]'), 'len(v:val)'), s:yank_separator)
return s:yank_to_register(hashes)
else
let filenames = a:lines[2:]
let candidates = []
for filename in filenames
" Don't forget trailing space in replacement.
let linenum = substitute(filename, '\v.{-}:(\d+):.*$', '+\1 ', '')
let name = substitute(filename, '\v(.{-}):\d+:.*$', '\1', '')
" fnameescape instead of shellescape because the file is consumed
" by vim rather than the shell
call add(candidates, linenum . fnameescape(name))
endfor
endif
for candidate in candidates
execute join([cmd, candidate])
endfor
endfunction
" If the file you're looking for is empty, then why does it even exist? It's a
" note. Just type its name. Hence we ignore lines with only space characters,
" and use the "\S" regex.
" Use a big ugly option list. The '.. ' is because fzf wants a term of the
" form 'N.. ' where N is a number.
" Use `command` in front of 'rg' to ignore aliases.
" The `' "\S" '` is so that the backslash itself doesn't require escaping.
" g:search_paths is already shell escaped, so we don't do it again
command! -nargs=* -bang NV
\ call fzf#run(
\ fzf#wrap({
\ 'sink*': function(exists('*NV_note_handler') ? 'NV_note_handler' : '<sid>handler'),
\ 'window': s:window_command,
\ 'source': join([
\ s:command,
\ 'rg',
\ '--follow',
\ s:use_ignore_files,
\ '--smart-case',
\ s:include_hidden,
\ '--line-number',
\ '--color never',
\ '--no-messages',
\ s:nv_ignore_pattern,
\ '--no-heading',
\ '--with-filename',
\ ((<q-args> is '') ?
\ '"\S"' :
\ shellescape(<q-args>)),
\ s:search_path_str,
\ s:format_path_expr,
\ '2>' . s:null_path,
\ ]),
\ s:window_direction: s:window_width,
\ 'options': join([
\ '--print-query',
\ '--ansi',
\ '--multi',
\ '--exact',
\ '--inline-info',
\ '--delimiter=":"',
\ '--with-nth=' . s:display_start_index ,
\ '--tiebreak=' . 'length,begin' ,
\ '--expect=' . s:expect_keys ,
\ '--bind=' . join([
\ 'alt-a:select-all',
\ 'alt-q:deselect-all',
\ 'alt-p:toggle-preview',
\ 'alt-u:page-up',
\ 'alt-d:page-down',
\ 'ctrl-w:backward-kill-word',
\ ], ','),
\ '--preview=' . shellescape(s:highlight_path_expr) ,
\ '--preview-window=' . join(filter(copy([
\ s:preview_direction,
\ s:preview_width,
\ s:wrap_text,
\ s:show_preview,
\ ]),
\ 'v:val != "" ')
\ ,':')
\ ])},<bang>0))

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB