diff --git a/Makefile b/Makefile index a438f8c..38e6866 100644 --- a/Makefile +++ b/Makefile @@ -20,6 +20,10 @@ gtk/%: ln -fs $(dotfiles)/$@ $(workspace)/.config/gtk-3.0/$(@F) ln -fs $(dotfiles)/$@ $(workspace)/.config/gtk-4.0/$(@F) +ipython/%: + mkdir -p $(workspace)/.ipython/profile_default + ln -fs $(dotfiles)/$@ $(workspace)/.ipython/profile_default/$(@F) + julia/%: mkdir -p $(workspace)/.julia/config ln -fs $(dotfiles)/$@ $(workspace)/.julia/config/$(@F) @@ -34,6 +38,7 @@ nix/%: # symlinks to ~/ ctags/% \ +editorconfig/% \ git/% \ r/% \ shells/% \ @@ -74,9 +79,11 @@ jupyter: $(wildcard jupyter/*) alacritty \ bin \ ctags \ +editorconfig \ emacs \ git \ gtk \ +ipython \ julia \ kitty \ nix \ diff --git a/editorconfig/editorconfig b/editorconfig/editorconfig new file mode 100644 index 0000000..8446648 --- /dev/null +++ b/editorconfig/editorconfig @@ -0,0 +1,10 @@ +root = true + +[*] +end_of_line = lf +indent_style = space +indent_size = 2 + +[*.py] +indent_style = space +indent_size = 4 diff --git a/firefox/treestyletab.css b/firefox/treestyletab.css index 8e8a4ac..9ea458b 100644 --- a/firefox/treestyletab.css +++ b/firefox/treestyletab.css @@ -1,14 +1,9 @@ -:root { - --tab-highlighted-glow: #E920A3; - --tab-surface-active: #5F5F5F; +:root.sidebar tab-item { + font-size: 10px !important; } -:root #background { - background: #4C4C4C; -} - -tab-item { - font-size: 12px !important; +:root.sidebar #background { + background-color: #F0F0F4 /* or something background color */; } tab-item tab-favicon { @@ -16,13 +11,5 @@ tab-item tab-favicon { } ::part(extra-contents-by-tst-active-tab-in-collapsed-tree_piro_sakura_ne_jp) { - background-color: #4C4C4C; + background-color: #F0F0F4; } - -/*tab-item:not(.loading):not(.active):not(.pinned) tab-favicon { - filter: drop-shadow(0px 0px 2.5px white); -} - -tab-item:not(.some-descendants-highlighted) ::part(extra-contents-by-tst-active-tab-in-collapsed-tree_piro_sakura_ne_jp favicon) { - filter: drop-shadow(0px 0px 5px white); -}*/ \ No newline at end of file diff --git a/git/gitconfig b/git/gitconfig index 934df59..245d27f 100644 --- a/git/gitconfig +++ b/git/gitconfig @@ -1,11 +1,19 @@ -[user] - name = gzagatti - email = gzagatti@users.noreply.github.com +[include] + path = .gitcredentials [core] autocrlf = input attributesfile = \"$HOME/.gitattributes\" [ui] color = true +[color "decorate"] + branch = green brightgreen + HEAD = red brightred + remoteBranch = blue brightblue + tag = magenta brightmagenta + stash = green + grafted = blue +[log] + graphColors=red,green,blue,magenta,cyan [push] default = simple [color] @@ -18,8 +26,6 @@ s = status -s lg = log --oneline --decorate --all --graph wdiff = diff --word-diff -[github] - user = gzagatti [hub] protocol = https [filter "lfs"] diff --git a/ipython/ipython_config.py b/ipython/ipython_config.py new file mode 100644 index 0000000..a31bae9 --- /dev/null +++ b/ipython/ipython_config.py @@ -0,0 +1,1330 @@ +# Configuration file for ipython. +# see: https://ipython.readthedocs.io/en/stable/config/intro.html +from pygments.token import Token + +#------------------------------------------------------------------------------ +# InteractiveShellApp(Configurable) configuration +#------------------------------------------------------------------------------ +## A Mixin for applications that start InteractiveShell instances. +# +# Provides configurables for loading extensions and executing files +# as part of configuring a Shell environment. +# +# The following methods should be called by the :meth:`initialize` method +# of the subclass: +# +# - :meth:`init_path` +# - :meth:`init_shell` (to be implemented by the subclass) +# - :meth:`init_gui_pylab` +# - :meth:`init_extensions` +# - :meth:`init_code` + +## Execute the given command string. +# Default: '' +# c.InteractiveShellApp.code_to_run = '' + +## Run the file referenced by the PYTHONSTARTUP environment +# variable at IPython startup. +# Default: True +# c.InteractiveShellApp.exec_PYTHONSTARTUP = True + +## List of files to run at IPython startup. +# Default: [] +# c.InteractiveShellApp.exec_files = [] + +## lines of code to run at IPython startup. +# Default: [] +# c.InteractiveShellApp.exec_lines = [] + +## A list of dotted module names of IPython extensions to load. +# Default: [] +# c.InteractiveShellApp.extensions = [] + +## Dotted module name(s) of one or more IPython extensions to load. +# +# For specifying extra extensions to load on the command-line. +# +# .. versionadded:: 7.10 +# Default: [] +# c.InteractiveShellApp.extra_extensions = [] + +## A file to be run +# Default: '' +# c.InteractiveShellApp.file_to_run = '' + +## Enable GUI event loop integration with any of ('asyncio', 'glut', 'gtk', +# 'gtk2', 'gtk3', 'gtk4', 'osx', 'pyglet', 'qt', 'qt5', 'qt6', 'tk', 'wx', +# 'gtk2', 'qt4'). +# Choices: any of ['asyncio', 'glut', 'gtk', 'gtk2', 'gtk3', 'gtk4', 'osx', 'pyglet', 'qt', 'qt5', 'qt6', 'tk', 'wx', 'gtk2', 'qt4'] (case-insensitive) or None +# Default: None +# c.InteractiveShellApp.gui = None + +## Should variables loaded at startup (by startup files, exec_lines, etc.) +# be hidden from tools like %who? +# Default: True +# c.InteractiveShellApp.hide_initial_ns = True + +## If True, IPython will not add the current working directory to sys.path. +# When False, the current working directory is added to sys.path, allowing imports +# of modules defined in the current directory. +# Default: False +# c.InteractiveShellApp.ignore_cwd = False + +## Configure matplotlib for interactive use with +# the default matplotlib backend. +# Choices: any of ['auto', 'agg', 'gtk', 'gtk3', 'gtk4', 'inline', 'ipympl', 'nbagg', 'notebook', 'osx', 'pdf', 'ps', 'qt', 'qt4', 'qt5', 'qt6', 'svg', 'tk', 'webagg', 'widget', 'wx'] (case-insensitive) or None +# Default: None +# c.InteractiveShellApp.matplotlib = 'tk' + +## Run the module as a script. +# Default: '' +# c.InteractiveShellApp.module_to_run = '' + +## Pre-load matplotlib and numpy for interactive use, +# selecting a particular matplotlib backend and loop integration. +# Choices: any of ['auto', 'agg', 'gtk', 'gtk3', 'gtk4', 'inline', 'ipympl', 'nbagg', 'notebook', 'osx', 'pdf', 'ps', 'qt', 'qt4', 'qt5', 'qt6', 'svg', 'tk', 'webagg', 'widget', 'wx'] (case-insensitive) or None +# Default: None +# c.InteractiveShellApp.pylab = None + +## If true, IPython will populate the user namespace with numpy, pylab, etc. +# and an ``import *`` is done from numpy and pylab, when using pylab mode. +# +# When False, pylab mode should not import any names into the user +# namespace. +# Default: True +# c.InteractiveShellApp.pylab_import_all = True + +## Reraise exceptions encountered loading IPython extensions? +# Default: False +# c.InteractiveShellApp.reraise_ipython_extension_failures = False + +#------------------------------------------------------------------------------ +# Application(SingletonConfigurable) configuration +#------------------------------------------------------------------------------ +## This is an application. + +## The date format used by logging formatters for %(asctime)s +# Default: '%Y-%m-%d %H:%M:%S' +# c.Application.log_datefmt = '%Y-%m-%d %H:%M:%S' + +## The Logging format template +# Default: '[%(name)s]%(highlevel)s %(message)s' +# c.Application.log_format = '[%(name)s]%(highlevel)s %(message)s' + +## Set the log level by value or name. +# Choices: any of [0, 10, 20, 30, 40, 50, 'DEBUG', 'INFO', 'WARN', 'ERROR', 'CRITICAL'] +# Default: 30 +# c.Application.log_level = 30 + +## Configure additional log handlers. +# +# The default stderr logs handler is configured by the log_level, log_datefmt +# and log_format settings. +# +# This configuration can be used to configure additional handlers (e.g. to +# output the log to a file) or for finer control over the default handlers. +# +# If provided this should be a logging configuration dictionary, for more +# information see: +# https://docs.python.org/3/library/logging.config.html#logging-config- +# dictschema +# +# This dictionary is merged with the base logging configuration which defines +# the following: +# +# * A logging formatter intended for interactive use called +# ``console``. +# * A logging handler that writes to stderr called +# ``console`` which uses the formatter ``console``. +# * A logger with the name of this application set to ``DEBUG`` +# level. +# +# This example adds a new handler that writes to a file: +# +# .. code-block:: python +# +# c.Application.logging_config = { +# "handlers": { +# "file": { +# "class": "logging.FileHandler", +# "level": "DEBUG", +# "filename": "", +# } +# }, +# "loggers": { +# "": { +# "level": "DEBUG", +# # NOTE: if you don't list the default "console" +# # handler here then it will be disabled +# "handlers": ["console", "file"], +# }, +# }, +# } +# Default: {} +# c.Application.logging_config = {} + +## Instead of starting the Application, dump configuration to stdout +# Default: False +# c.Application.show_config = False + +## Instead of starting the Application, dump configuration to stdout (as JSON) +# Default: False +# c.Application.show_config_json = False + +#------------------------------------------------------------------------------ +# BaseIPythonApplication(Application) configuration +#------------------------------------------------------------------------------ +# Default: False +# c.BaseIPythonApplication.add_ipython_dir_to_sys_path = False + +## Whether to create profile dir if it doesn't exist +# Default: False +# c.BaseIPythonApplication.auto_create = False + +## Whether to install the default config files into the profile dir. +# If a new profile is being created, and IPython contains config files for that +# profile, then they will be staged into the new directory. Otherwise, +# default config files will be automatically generated. +# Default: False +# c.BaseIPythonApplication.copy_config_files = False + +## Path to an extra config file to load. +# +# If specified, load this config file in addition to any other IPython +# config. +# Default: '' +# c.BaseIPythonApplication.extra_config_file = '' + +## The name of the IPython directory. This directory is used for logging +# configuration (through profiles), history storage, etc. The default is usually +# $HOME/.ipython. This option can also be specified through the environment +# variable IPYTHONDIR. +# Default: '' +# c.BaseIPythonApplication.ipython_dir = '' + +## The date format used by logging formatters for %(asctime)s +# See also: Application.log_datefmt +# c.BaseIPythonApplication.log_datefmt = '%Y-%m-%d %H:%M:%S' + +## The Logging format template +# See also: Application.log_format +# c.BaseIPythonApplication.log_format = '[%(name)s]%(highlevel)s %(message)s' + +## Set the log level by value or name. +# See also: Application.log_level +# c.BaseIPythonApplication.log_level = 30 + +## +# See also: Application.logging_config +# c.BaseIPythonApplication.logging_config = {} + +## Whether to overwrite existing config files when copying +# Default: False +# c.BaseIPythonApplication.overwrite = False + +## The IPython profile to use. +# Default: 'default' +# c.BaseIPythonApplication.profile = 'default' + +## Instead of starting the Application, dump configuration to stdout +# See also: Application.show_config +# c.BaseIPythonApplication.show_config = False + +## Instead of starting the Application, dump configuration to stdout (as JSON) +# See also: Application.show_config_json +# c.BaseIPythonApplication.show_config_json = False + +## Create a massive crash report when IPython encounters what may be an +# internal error. The default is to append a short message to the +# usual traceback +# Default: False +# c.BaseIPythonApplication.verbose_crash = False + +#------------------------------------------------------------------------------ +# TerminalIPythonApp(BaseIPythonApplication, InteractiveShellApp) configuration +#------------------------------------------------------------------------------ +# See also: BaseIPythonApplication.add_ipython_dir_to_sys_path +# c.TerminalIPythonApp.add_ipython_dir_to_sys_path = False + +## Execute the given command string. +# See also: InteractiveShellApp.code_to_run +# c.TerminalIPythonApp.code_to_run = '' + +## Whether to install the default config files into the profile dir. +# See also: BaseIPythonApplication.copy_config_files +# c.TerminalIPythonApp.copy_config_files = False + +## Whether to display a banner upon starting IPython. +# Default: True +# c.TerminalIPythonApp.display_banner = True + +## Run the file referenced by the PYTHONSTARTUP environment +# See also: InteractiveShellApp.exec_PYTHONSTARTUP +# c.TerminalIPythonApp.exec_PYTHONSTARTUP = True + +## List of files to run at IPython startup. +# See also: InteractiveShellApp.exec_files +# c.TerminalIPythonApp.exec_files = [] + +## lines of code to run at IPython startup. +# See also: InteractiveShellApp.exec_lines +# c.TerminalIPythonApp.exec_lines = [] + +## A list of dotted module names of IPython extensions to load. +# See also: InteractiveShellApp.extensions +# c.TerminalIPythonApp.extensions = [] + +## Path to an extra config file to load. +# See also: BaseIPythonApplication.extra_config_file +# c.TerminalIPythonApp.extra_config_file = '' + +## +# See also: InteractiveShellApp.extra_extensions +# c.TerminalIPythonApp.extra_extensions = [] + +## A file to be run +# See also: InteractiveShellApp.file_to_run +# c.TerminalIPythonApp.file_to_run = '' + +## If a command or file is given via the command-line, +# e.g. 'ipython foo.py', start an interactive shell after executing the +# file or command. +# Default: False +# c.TerminalIPythonApp.force_interact = False + +## Enable GUI event loop integration with any of ('asyncio', 'glut', 'gtk', +# 'gtk2', 'gtk3', 'gtk4', 'osx', 'pyglet', 'qt', 'qt5', 'qt6', 'tk', 'wx', +# 'gtk2', 'qt4'). +# See also: InteractiveShellApp.gui +# c.TerminalIPythonApp.gui = None + +## Should variables loaded at startup (by startup files, exec_lines, etc.) +# See also: InteractiveShellApp.hide_initial_ns +# c.TerminalIPythonApp.hide_initial_ns = True + +## If True, IPython will not add the current working directory to sys.path. +# See also: InteractiveShellApp.ignore_cwd +# c.TerminalIPythonApp.ignore_cwd = False + +## Class to use to instantiate the TerminalInteractiveShell object. Useful for +# custom Frontends +# Default: 'IPython.terminal.interactiveshell.TerminalInteractiveShell' +# c.TerminalIPythonApp.interactive_shell_class = 'IPython.terminal.interactiveshell.TerminalInteractiveShell' + +## +# See also: BaseIPythonApplication.ipython_dir +# c.TerminalIPythonApp.ipython_dir = '' + +## The date format used by logging formatters for %(asctime)s +# See also: Application.log_datefmt +# c.TerminalIPythonApp.log_datefmt = '%Y-%m-%d %H:%M:%S' + +## The Logging format template +# See also: Application.log_format +# c.TerminalIPythonApp.log_format = '[%(name)s]%(highlevel)s %(message)s' + +## Set the log level by value or name. +# See also: Application.log_level +# c.TerminalIPythonApp.log_level = 30 + +## +# See also: Application.logging_config +# c.TerminalIPythonApp.logging_config = {} + +## Configure matplotlib for interactive use with +# See also: InteractiveShellApp.matplotlib +# c.TerminalIPythonApp.matplotlib = None + +## Run the module as a script. +# See also: InteractiveShellApp.module_to_run +# c.TerminalIPythonApp.module_to_run = '' + +## Whether to overwrite existing config files when copying +# See also: BaseIPythonApplication.overwrite +# c.TerminalIPythonApp.overwrite = False + +## The IPython profile to use. +# See also: BaseIPythonApplication.profile +# c.TerminalIPythonApp.profile = 'default' + +## Pre-load matplotlib and numpy for interactive use, +# See also: InteractiveShellApp.pylab +# c.TerminalIPythonApp.pylab = None + +## If true, IPython will populate the user namespace with numpy, pylab, etc. +# See also: InteractiveShellApp.pylab_import_all +# c.TerminalIPythonApp.pylab_import_all = True + +## Start IPython quickly by skipping the loading of config files. +# Default: False +# c.TerminalIPythonApp.quick = False + +## Reraise exceptions encountered loading IPython extensions? +# See also: InteractiveShellApp.reraise_ipython_extension_failures +# c.TerminalIPythonApp.reraise_ipython_extension_failures = False + +## Instead of starting the Application, dump configuration to stdout +# See also: Application.show_config +# c.TerminalIPythonApp.show_config = False + +## Instead of starting the Application, dump configuration to stdout (as JSON) +# See also: Application.show_config_json +# c.TerminalIPythonApp.show_config_json = False + +## Create a massive crash report when IPython encounters what may be an +# See also: BaseIPythonApplication.verbose_crash +# c.TerminalIPythonApp.verbose_crash = False + +#------------------------------------------------------------------------------ +# InteractiveShell(SingletonConfigurable) configuration +#------------------------------------------------------------------------------ +## An enhanced, interactive shell for Python. + +## 'all', 'last', 'last_expr' or 'none', 'last_expr_or_assign' specifying which +# nodes should be run interactively (displaying output from expressions). +# Choices: any of ['all', 'last', 'last_expr', 'none', 'last_expr_or_assign'] +# Default: 'last_expr' +# c.InteractiveShell.ast_node_interactivity = 'last_expr' + +## A list of ast.NodeTransformer subclass instances, which will be applied to +# user input before code is run. +# Default: [] +# c.InteractiveShell.ast_transformers = [] + +## Automatically run await statement in the top level repl. +# Default: True +# c.InteractiveShell.autoawait = True + +## Make IPython automatically call any callable object even if you didn't type +# explicit parentheses. For example, 'str 43' becomes 'str(43)' automatically. +# The value can be '0' to disable the feature, '1' for 'smart' autocall, where +# it is not applied if there are no more arguments on the line, and '2' for +# 'full' autocall, where all callable objects are automatically called (even if +# no arguments are present). +# Choices: any of [0, 1, 2] +# Default: 0 +# c.InteractiveShell.autocall = 0 + +## Autoindent IPython code entered interactively. +# Default: True +c.TerminalInteractiveShell.autoindent = False + +## Enable magic commands to be called without the leading %. +# Default: True +# c.InteractiveShell.automagic = True + +## The part of the banner to be printed before the profile +# Default: "Python 3.9.8 (main, May 7 2024, 14:59:27) \nType 'copyright', 'credits' or 'license' for more information\nIPython 8.18.1 -- An enhanced Interactive Python. Type '?' for help.\n" +# c.InteractiveShell.banner1 = "Python 3.9.8 (main, May 7 2024, 14:59:27) \nType 'copyright', 'credits' or 'license' for more information\nIPython 8.18.1 -- An enhanced Interactive Python. Type '?' for help.\n" + +## The part of the banner to be printed after the profile +# Default: '' +# c.InteractiveShell.banner2 = '' + +## Set the size of the output cache. The default is 1000, you can change it +# permanently in your config file. Setting it to 0 completely disables the +# caching system, and the minimum value accepted is 3 (if you provide a value +# less than 3, it is reset to 0 and a warning is issued). This limit is defined +# because otherwise you'll spend more time re-flushing a too small cache than +# working +# Default: 1000 +# c.InteractiveShell.cache_size = 1000 + +## Use colors for displaying information about objects. Because this information +# is passed through a pager (like 'less'), and some pagers get confused with +# color codes, this capability can be turned off. +# Default: True +# c.InteractiveShell.color_info = True + +## Set the color scheme (NoColor, Neutral, Linux, or LightBG). +# Choices: any of ['Neutral', 'NoColor', 'LightBG', 'Linux'] (case-insensitive) +# Default: 'Neutral' +# c.InteractiveShell.colors = 'Neutral' + +# Default: False +# c.InteractiveShell.debug = False + +## Don't call post-execute functions that have failed in the past. +# Default: False +# c.InteractiveShell.disable_failing_post_execute = False + +## If True, anything that would be passed to the pager +# will be displayed as regular output instead. +# Default: False +# c.InteractiveShell.display_page = False + +## (Provisional API) enables html representation in mime bundles sent to pagers. +# Default: False +# c.InteractiveShell.enable_html_pager = False + +## Total length of command history +# Default: 10000 +# c.InteractiveShell.history_length = 10000 + +## The number of saved history entries to be loaded into the history buffer at +# startup. +# Default: 1000 +# c.InteractiveShell.history_load_length = 1000 + +## Class to use to instantiate the shell inspector +# Default: 'IPython.core.oinspect.Inspector' +# c.InteractiveShell.inspector_class = 'IPython.core.oinspect.Inspector' + +# Default: '' +# c.InteractiveShell.ipython_dir = '' + +## Start logging to the given file in append mode. Use `logfile` to specify a log +# file to **overwrite** logs to. +# Default: '' +# c.InteractiveShell.logappend = '' + +## The name of the logfile to use. +# Default: '' +# c.InteractiveShell.logfile = '' + +## Start logging to the default log file in overwrite mode. Use `logappend` to +# specify a log file to **append** logs to. +# Default: False +# c.InteractiveShell.logstart = False + +## Select the loop runner that will be used to execute top-level asynchronous +# code +# Default: 'IPython.core.interactiveshell._asyncio_runner' +# c.InteractiveShell.loop_runner = 'IPython.core.interactiveshell._asyncio_runner' + +# Choices: any of [0, 1, 2] +# Default: 0 +# c.InteractiveShell.object_info_string_level = 0 + +## Automatically call the pdb debugger after every exception. +# Default: False +# c.InteractiveShell.pdb = False + +# Default: False +# c.InteractiveShell.quiet = False + +# Default: '\n' +# c.InteractiveShell.separate_in = '\n' + +# Default: '' +# c.InteractiveShell.separate_out = '' + +# Default: '' +# c.InteractiveShell.separate_out2 = '' + +## Show rewritten input, e.g. for autocall. +# Default: True +# c.InteractiveShell.show_rewritten_input = True + +## Enables rich html representation of docstrings. (This requires the docrepr +# module). +# Default: False +# c.InteractiveShell.sphinxify_docstring = False + +## Warn if running in a virtual environment with no IPython installed (so IPython +# from the global environment is used). +# Default: True +# c.InteractiveShell.warn_venv = True + +# Default: True +# c.InteractiveShell.wildcards_case_sensitive = True + +## Switch modes for the IPython exception handlers. +# Choices: any of ['Context', 'Plain', 'Verbose', 'Minimal'] (case-insensitive) +# Default: 'Context' +# c.InteractiveShell.xmode = 'Context' + +#------------------------------------------------------------------------------ +# TerminalInteractiveShell(InteractiveShell) configuration +#------------------------------------------------------------------------------ +## +# See also: InteractiveShell.ast_node_interactivity +# c.TerminalInteractiveShell.ast_node_interactivity = 'last_expr' + +## +# See also: InteractiveShell.ast_transformers +# c.TerminalInteractiveShell.ast_transformers = [] + +## Automatically add/delete closing bracket or quote when opening bracket or +# quote is entered/deleted. Brackets: (), [], {} Quotes: '', "" +# Default: False +# c.TerminalInteractiveShell.auto_match = False + +## +# See also: InteractiveShell.autoawait +# c.TerminalInteractiveShell.autoawait = True + +## +# See also: InteractiveShell.autocall +# c.TerminalInteractiveShell.autocall = 0 + +## Autoformatter to reformat Terminal code. Can be `'black'`, `'yapf'` or `None` +# Default: None +# c.TerminalInteractiveShell.autoformatter = None + +## +# See also: InteractiveShell.autoindent +# c.TerminalInteractiveShell.autoindent = True + +## +# See also: InteractiveShell.automagic +# c.TerminalInteractiveShell.automagic = True + +## Specifies from which source automatic suggestions are provided. Can be set to +# ``'NavigableAutoSuggestFromHistory'`` (:kbd:`up` and :kbd:`down` swap +# suggestions), ``'AutoSuggestFromHistory'``, or ``None`` to disable automatic +# suggestions. Default is `'NavigableAutoSuggestFromHistory`'. +# Default: 'NavigableAutoSuggestFromHistory' +# c.TerminalInteractiveShell.autosuggestions_provider = 'NavigableAutoSuggestFromHistory' + +## The part of the banner to be printed before the profile +# See also: InteractiveShell.banner1 +# c.TerminalInteractiveShell.banner1 = "Python 3.9.8 (main, May 7 2024, 14:59:27) \nType 'copyright', 'credits' or 'license' for more information\nIPython 8.18.1 -- An enhanced Interactive Python. Type '?' for help.\n" + +## The part of the banner to be printed after the profile +# See also: InteractiveShell.banner2 +# c.TerminalInteractiveShell.banner2 = '' + +## +# See also: InteractiveShell.cache_size +# c.TerminalInteractiveShell.cache_size = 1000 + +## +# See also: InteractiveShell.color_info +# c.TerminalInteractiveShell.color_info = True + +## Set the color scheme (NoColor, Neutral, Linux, or LightBG). +# See also: InteractiveShell.colors +# c.TerminalInteractiveShell.colors = 'Neutral' + +## Set to confirm when you try to exit IPython with an EOF (Control-D in Unix, +# Control-Z/Enter in Windows). By typing 'exit' or 'quit', you can force a +# direct exit without any confirmation. +# Default: True +c.TerminalInteractiveShell.confirm_exit = False + +# See also: InteractiveShell.debug +# c.TerminalInteractiveShell.debug = False + +## File in which to store and read history +# Default: '~/.pdbhistory' +# c.TerminalInteractiveShell.debugger_history_file = '~/.pdbhistory' + +## Don't call post-execute functions that have failed in the past. +# See also: InteractiveShell.disable_failing_post_execute +# c.TerminalInteractiveShell.disable_failing_post_execute = False + +## Options for displaying tab completions, 'column', 'multicolumn', and +# 'readlinelike'. These options are for `prompt_toolkit`, see `prompt_toolkit` +# documentation for more information. +# Choices: any of ['column', 'multicolumn', 'readlinelike'] +# Default: 'multicolumn' +c.TerminalInteractiveShell.display_completions = 'readlinelike' + +## If True, anything that would be passed to the pager +# See also: InteractiveShell.display_page +# c.TerminalInteractiveShell.display_page = False + +## Shortcut style to use at the prompt. 'vi' or 'emacs'. +# Default: 'emacs' +c.TerminalInteractiveShell.editing_mode = 'vi' + +## Set the editor used by IPython (default to $EDITOR/vi/notepad). +# Default: '/home/linuxbrew/.linuxbrew/bin/nvim' +# c.TerminalInteractiveShell.editor = '/home/linuxbrew/.linuxbrew/bin/nvim' + +## Add shortcuts from 'emacs' insert mode to 'vi' insert mode. +# Default: True +c.TerminalInteractiveShell.emacs_bindings_in_vi_insert_mode = True + +## Allows to enable/disable the prompt toolkit history search +# Default: True +# c.TerminalInteractiveShell.enable_history_search = True + +## +# See also: InteractiveShell.enable_html_pager +# c.TerminalInteractiveShell.enable_html_pager = False + +## Enable vi (v) or Emacs (C-X C-E) shortcuts to open an external editor. This is +# in addition to the F2 binding, which is always enabled. +# Default: False +# c.TerminalInteractiveShell.extra_open_editor_shortcuts = False + +## Provide an alternative handler to be called when the user presses Return. This +# is an advanced option intended for debugging, which may be changed or removed +# in later releases. +# Default: None +# c.TerminalInteractiveShell.handle_return = None + +## Highlight matching brackets. +# Default: True +# c.TerminalInteractiveShell.highlight_matching_brackets = True + +## The name or class of a Pygments style to use for syntax +# highlighting. To see available styles, run `pygmentize -L styles`. +# Default: traitlets.Undefined +# c.TerminalInteractiveShell.highlighting_style = traitlets.Undefined + +## Override highlighting format for specific tokens +# Default: {} +# from: https://github.com/jupyter/jupyter_console/blob/fddbc42d2e0be85feace1fe783a05e2b569fceae/jupyter_console/ptshell.py#L512 +c.TerminalInteractiveShell.highlighting_style_overrides = { + Token.Prompt: '#009900', + Token.PromptNum: '#00ff00 bold', + Token.OutPrompt: '#ff2200', + Token.OutPromptNum: '#ff0000 bold', + Token.RemotePrompt: '#999900', + Token.Number: '#007700', + Token.Operator: 'noinherit', + Token.String: '#BB6622', + Token.Name.Function: '#2080D0', + Token.Name.Class: 'bold #2080D0', + Token.Name.Namespace: 'bold #2080D0', +} + + +## Total length of command history +# See also: InteractiveShell.history_length +# c.TerminalInteractiveShell.history_length = 10000 + +## +# See also: InteractiveShell.history_load_length +# c.TerminalInteractiveShell.history_load_length = 1000 + +## Class to use to instantiate the shell inspector +# See also: InteractiveShell.inspector_class +# c.TerminalInteractiveShell.inspector_class = 'IPython.core.oinspect.Inspector' + +# See also: InteractiveShell.ipython_dir +# c.TerminalInteractiveShell.ipython_dir = '' + +## +# See also: InteractiveShell.logappend +# c.TerminalInteractiveShell.logappend = '' + +## +# See also: InteractiveShell.logfile +# c.TerminalInteractiveShell.logfile = '' + +## +# See also: InteractiveShell.logstart +# c.TerminalInteractiveShell.logstart = False + +## Select the loop runner that will be used to execute top-level asynchronous +# code +# See also: InteractiveShell.loop_runner +# c.TerminalInteractiveShell.loop_runner = 'IPython.core.interactiveshell._asyncio_runner' + +# Default: {} +# c.TerminalInteractiveShell.mime_renderers = {} + +## Cursor shape changes depending on vi mode: beam in vi insert mode, block in +# nav mode, underscore in replace mode. +# Default: True +c.TerminalInteractiveShell.modal_cursor = True + +## Enable mouse support in the prompt (Note: prevents selecting text with the +# mouse) +# Default: False +# c.TerminalInteractiveShell.mouse_support = False + +# See also: InteractiveShell.object_info_string_level +# c.TerminalInteractiveShell.object_info_string_level = 0 + +## +# See also: InteractiveShell.pdb +# c.TerminalInteractiveShell.pdb = False + +## Display the current vi mode (when using vi editing mode). +# Default: True +c.TerminalInteractiveShell.prompt_includes_vi_mode = False + +## Class used to generate Prompt token for prompt_toolkit +# Default: 'IPython.terminal.prompts.Prompts' +# c.TerminalInteractiveShell.prompts_class = 'IPython.terminal.prompts.Prompts' + +# See also: InteractiveShell.quiet +# c.TerminalInteractiveShell.quiet = False + +# See also: InteractiveShell.separate_in +# c.TerminalInteractiveShell.separate_in = '\n' + +# See also: InteractiveShell.separate_out +# c.TerminalInteractiveShell.separate_out = '' + +# See also: InteractiveShell.separate_out2 +# c.TerminalInteractiveShell.separate_out2 = '' + +## Add, disable or modifying shortcuts. +# +# Each entry on the list should be a dictionary with ``command`` key +# identifying the target function executed by the shortcut and at least +# one of the following: +# +# - ``match_keys``: list of keys used to match an existing shortcut, +# - ``match_filter``: shortcut filter used to match an existing shortcut, +# - ``new_keys``: list of keys to set, +# - ``new_filter``: a new shortcut filter to set +# +# The filters have to be composed of pre-defined verbs and joined by one +# of the following conjunctions: ``&`` (and), ``|`` (or), ``~`` (not). +# The pre-defined verbs are: +# +# - `always` +# - `never` +# - `has_line_below` +# - `has_line_above` +# - `is_cursor_at_the_end_of_line` +# - `has_selection` +# - `has_suggestion` +# - `vi_mode` +# - `vi_insert_mode` +# - `emacs_insert_mode` +# - `emacs_like_insert_mode` +# - `has_completions` +# - `insert_mode` +# - `default_buffer_focused` +# - `search_buffer_focused` +# - `ebivim` +# - `supports_suspend` +# - `is_windows_os` +# - `auto_match` +# - `focused_insert` +# - `not_inside_unclosed_string` +# - `readline_like_completions` +# - `preceded_by_paired_double_quotes` +# - `preceded_by_paired_single_quotes` +# - `preceded_by_raw_str_prefix` +# - `preceded_by_two_double_quotes` +# - `preceded_by_two_single_quotes` +# - `followed_by_closing_paren_or_end` +# - `preceded_by_opening_round_paren` +# - `preceded_by_opening_bracket` +# - `preceded_by_opening_brace` +# - `preceded_by_double_quote` +# - `preceded_by_single_quote` +# - `followed_by_closing_round_paren` +# - `followed_by_closing_bracket` +# - `followed_by_closing_brace` +# - `followed_by_double_quote` +# - `followed_by_single_quote` +# - `navigable_suggestions` +# - `cursor_in_leading_ws` +# - `pass_through` +# +# To disable a shortcut set ``new_keys`` to an empty list. +# To add a shortcut add key ``create`` with value ``True``. +# +# When modifying/disabling shortcuts, ``match_keys``/``match_filter`` can +# be omitted if the provided specification uniquely identifies a shortcut +# to be modified/disabled. When modifying a shortcut ``new_filter`` or +# ``new_keys`` can be omitted which will result in reuse of the existing +# filter/keys. +# +# Only shortcuts defined in IPython (and not default prompt-toolkit +# shortcuts) can be modified or disabled. The full list of shortcuts, +# command identifiers and filters is available under +# :ref:`terminal-shortcuts-list`. +# Default: [] +# c.TerminalInteractiveShell.shortcuts = [] + +## Show rewritten input, e.g. for autocall. +# See also: InteractiveShell.show_rewritten_input +# c.TerminalInteractiveShell.show_rewritten_input = True + +## Use `raw_input` for the REPL, without completion and prompt colors. +# +# Useful when controlling IPython as a subprocess, and piping STDIN/OUT/ERR. Known usage are: +# IPython own testing machinery, and emacs inferior-shell integration through elpy. +# +# This mode default to `True` if the `IPY_TEST_SIMPLE_PROMPT` +# environment variable is set, or the current terminal is not a tty. +# Default: False +# c.TerminalInteractiveShell.simple_prompt = False + +## Number of line at the bottom of the screen to reserve for the tab completion +# menu, search history, ...etc, the height of these menus will at most this +# value. Increase it is you prefer long and skinny menus, decrease for short and +# wide. +# Default: 6 +# c.TerminalInteractiveShell.space_for_menu = 6 + +## +# See also: InteractiveShell.sphinxify_docstring +# c.TerminalInteractiveShell.sphinxify_docstring = False + +## Automatically set the terminal title +# Default: True +# c.TerminalInteractiveShell.term_title = True + +## Customize the terminal title format. This is a python format string. +# Available substitutions are: {cwd}. +# Default: 'IPython: {cwd}' +# c.TerminalInteractiveShell.term_title_format = 'IPython: {cwd}' + +## The time in milliseconds that is waited for a mapped key +# sequence to complete. +# Default: 0.5 +# c.TerminalInteractiveShell.timeoutlen = 0.5 + +## Use 24bit colors instead of 256 colors in prompt highlighting. +# If your terminal supports true color, the following command should +# print ``TRUECOLOR`` in orange:: +# +# printf "\x1b[38;2;255;100;0mTRUECOLOR\x1b[0m\n" +# Default: False +# c.TerminalInteractiveShell.true_color = False + +## The time in milliseconds that is waited for a key code +# to complete. +# Default: 0.01 +# c.TerminalInteractiveShell.ttimeoutlen = 0.01 + +## Warn if running in a virtual environment with no IPython installed (so IPython +# from the global environment is used). +# See also: InteractiveShell.warn_venv +# c.TerminalInteractiveShell.warn_venv = True + +# See also: InteractiveShell.wildcards_case_sensitive +# c.TerminalInteractiveShell.wildcards_case_sensitive = True + +## Switch modes for the IPython exception handlers. +# See also: InteractiveShell.xmode +# c.TerminalInteractiveShell.xmode = 'Context' + +#------------------------------------------------------------------------------ +# HistoryAccessor(HistoryAccessorBase) configuration +#------------------------------------------------------------------------------ +## Access the history database without adding to it. +# +# This is intended for use by standalone history tools. IPython shells use +# HistoryManager, below, which is a subclass of this. + +## Options for configuring the SQLite connection +# +# These options are passed as keyword args to sqlite3.connect +# when establishing database connections. +# Default: {} +# c.HistoryAccessor.connection_options = {} + +## enable the SQLite history +# +# set enabled=False to disable the SQLite history, +# in which case there will be no stored history, no SQLite connection, +# and no background saving thread. This may be necessary in some +# threaded environments where IPython is embedded. +# Default: True +# c.HistoryAccessor.enabled = True + +## Path to file to use for SQLite history database. +# +# By default, IPython will put the history database in the IPython +# profile directory. If you would rather share one history among +# profiles, you can set this value in each, so that they are consistent. +# +# Due to an issue with fcntl, SQLite is known to misbehave on some NFS +# mounts. If you see IPython hanging, try setting this to something on a +# local disk, e.g:: +# +# ipython --HistoryManager.hist_file=/tmp/ipython_hist.sqlite +# +# you can also use the specific value `:memory:` (including the colon +# at both end but not the back ticks), to avoid creating an history file. +# Default: traitlets.Undefined +# c.HistoryAccessor.hist_file = traitlets.Undefined + +#------------------------------------------------------------------------------ +# HistoryManager(HistoryAccessor) configuration +#------------------------------------------------------------------------------ +## A class to organize all history-related functionality in one place. + +## Options for configuring the SQLite connection +# See also: HistoryAccessor.connection_options +# c.HistoryManager.connection_options = {} + +## Write to database every x commands (higher values save disk access & power). +# Values of 1 or less effectively disable caching. +# Default: 0 +# c.HistoryManager.db_cache_size = 0 + +## Should the history database include output? (default: no) +# Default: False +# c.HistoryManager.db_log_output = False + +## enable the SQLite history +# See also: HistoryAccessor.enabled +# c.HistoryManager.enabled = True + +## Path to file to use for SQLite history database. +# See also: HistoryAccessor.hist_file +# c.HistoryManager.hist_file = traitlets.Undefined + +#------------------------------------------------------------------------------ +# MagicsManager(Configurable) configuration +#------------------------------------------------------------------------------ +## Object that handles all magic-related functionality for IPython. + +## Automatically call line magics without requiring explicit % prefix +# Default: True +# c.MagicsManager.auto_magic = True + +## Mapping from magic names to modules to load. +# +# This can be used in IPython/IPykernel configuration to declare lazy magics +# that will only be imported/registered on first use. +# +# For example:: +# +# c.MagicsManager.lazy_magics = { +# "my_magic": "slow.to.import", +# "my_other_magic": "also.slow", +# } +# +# On first invocation of `%my_magic`, `%%my_magic`, `%%my_other_magic` or +# `%%my_other_magic`, the corresponding module will be loaded as an ipython +# extensions as if you had previously done `%load_ext ipython`. +# +# Magics names should be without percent(s) as magics can be both cell and line +# magics. +# +# Lazy loading happen relatively late in execution process, and complex +# extensions that manipulate Python/IPython internal state or global state might +# not support lazy loading. +# Default: {} +# c.MagicsManager.lazy_magics = {} + +#------------------------------------------------------------------------------ +# ProfileDir(LoggingConfigurable) configuration +#------------------------------------------------------------------------------ +## An object to manage the profile directory and its resources. +# +# The profile directory is used by all IPython applications, to manage +# configuration, logging and security. +# +# This object knows how to find, create and manage these directories. This +# should be used by any code that wants to handle profiles. + +## Set the profile location directly. This overrides the logic used by the +# `profile` option. +# Default: '' +# c.ProfileDir.location = '' + +#------------------------------------------------------------------------------ +# BaseFormatter(Configurable) configuration +#------------------------------------------------------------------------------ +## A base formatter class that is configurable. +# +# This formatter should usually be used as the base class of all formatters. +# It is a traited :class:`Configurable` class and includes an extensible +# API for users to determine how their objects are formatted. The following +# logic is used to find a function to format an given object. +# +# 1. The object is introspected to see if it has a method with the name +# :attr:`print_method`. If is does, that object is passed to that method +# for formatting. +# 2. If no print method is found, three internal dictionaries are consulted +# to find print method: :attr:`singleton_printers`, :attr:`type_printers` +# and :attr:`deferred_printers`. +# +# Users should use these dictionaries to register functions that will be +# used to compute the format data for their objects (if those objects don't +# have the special print methods). The easiest way of using these +# dictionaries is through the :meth:`for_type` and :meth:`for_type_by_name` +# methods. +# +# If no function/callable is found to compute the format data, ``None`` is +# returned and this format type is not used. + +# Default: {} +# c.BaseFormatter.deferred_printers = {} + +# Default: True +# c.BaseFormatter.enabled = True + +# Default: {} +# c.BaseFormatter.singleton_printers = {} + +# Default: {} +# c.BaseFormatter.type_printers = {} + +#------------------------------------------------------------------------------ +# PlainTextFormatter(BaseFormatter) configuration +#------------------------------------------------------------------------------ +## The default pretty-printer. +# +# This uses :mod:`IPython.lib.pretty` to compute the format data of +# the object. If the object cannot be pretty printed, :func:`repr` is used. +# See the documentation of :mod:`IPython.lib.pretty` for details on +# how to write pretty printers. Here is a simple example:: +# +# def dtype_pprinter(obj, p, cycle): +# if cycle: +# return p.text('dtype(...)') +# if hasattr(obj, 'fields'): +# if obj.fields is None: +# p.text(repr(obj)) +# else: +# p.begin_group(7, 'dtype([') +# for i, field in enumerate(obj.descr): +# if i > 0: +# p.text(',') +# p.breakable() +# p.pretty(field) +# p.end_group(7, '])') + +# See also: BaseFormatter.deferred_printers +# c.PlainTextFormatter.deferred_printers = {} + +# Default: '' +# c.PlainTextFormatter.float_precision = '' + +## Truncate large collections (lists, dicts, tuples, sets) to this size. +# +# Set to 0 to disable truncation. +# Default: 1000 +# c.PlainTextFormatter.max_seq_length = 1000 + +# Default: 79 +# c.PlainTextFormatter.max_width = 79 + +# Default: '\n' +# c.PlainTextFormatter.newline = '\n' + +# Default: True +# c.PlainTextFormatter.pprint = True + +# See also: BaseFormatter.singleton_printers +# c.PlainTextFormatter.singleton_printers = {} + +# See also: BaseFormatter.type_printers +# c.PlainTextFormatter.type_printers = {} + +# Default: False +# c.PlainTextFormatter.verbose = False + +#------------------------------------------------------------------------------ +# Completer(Configurable) configuration +#------------------------------------------------------------------------------ +## Enable auto-closing dictionary keys. +# +# When enabled string keys will be suffixed with a final quote (matching the +# opening quote), tuple keys will also receive a separating comma if needed, and +# keys which are final will receive a closing bracket (``]``). +# Default: False +# c.Completer.auto_close_dict_keys = False + +## Enable unicode completions, e.g. \alpha . Includes completion of latex +# commands, unicode names, and expanding unicode characters back to latex +# commands. +# Default: True +# c.Completer.backslash_combining_completions = True + +## Enable debug for the Completer. Mostly print extra information for +# experimental jedi integration. +# Default: False +# c.Completer.debug = False + +## Policy for code evaluation under completion. +# +# Successive options allow to enable more eager evaluation for better +# completion suggestions, including for nested dictionaries, nested lists, +# or even results of function calls. +# Setting ``unsafe`` or higher can lead to evaluation of arbitrary user +# code on :kbd:`Tab` with potentially unwanted or dangerous side effects. +# +# Allowed values are: +# +# - ``forbidden``: no evaluation of code is permitted, +# - ``minimal``: evaluation of literals and access to built-in namespace; +# no item/attribute evaluationm no access to locals/globals, +# no evaluation of any operations or comparisons. +# - ``limited``: access to all namespaces, evaluation of hard-coded methods +# (for example: :any:`dict.keys`, :any:`object.__getattr__`, +# :any:`object.__getitem__`) on allow-listed objects (for example: +# :any:`dict`, :any:`list`, :any:`tuple`, ``pandas.Series``), +# - ``unsafe``: evaluation of all methods and function calls but not of +# syntax with side-effects like `del x`, +# - ``dangerous``: completely arbitrary evaluation. +# Choices: any of ['forbidden', 'minimal', 'limited', 'unsafe', 'dangerous'] +# Default: 'limited' +# c.Completer.evaluation = 'limited' + +## Activate greedy completion. +# +# .. deprecated:: 8.8 +# Use :std:configtrait:`Completer.evaluation` and :std:configtrait:`Completer.auto_close_dict_keys` instead. +# +# When enabled in IPython 8.8 or newer, changes configuration as +# follows: +# +# - ``Completer.evaluation = 'unsafe'`` +# - ``Completer.auto_close_dict_keys = True`` +# Default: False +# c.Completer.greedy = False + +## Experimental: restrict time (in milliseconds) during which Jedi can compute types. +# Set to 0 to stop computing types. Non-zero value lower than 100ms may hurt +# performance by preventing jedi to build its cache. +# Default: 400 +# c.Completer.jedi_compute_type_timeout = 400 + +## Experimental: Use Jedi to generate autocompletions. Default to True if jedi is +# installed. +# Default: True +# c.Completer.use_jedi = True + +#------------------------------------------------------------------------------ +# IPCompleter(Completer) configuration +#------------------------------------------------------------------------------ +## Extension of the completer class with IPython-specific features + +## +# See also: Completer.auto_close_dict_keys +# c.IPCompleter.auto_close_dict_keys = False + +## Enable unicode completions, e.g. \alpha . Includes completion of latex +# commands, unicode names, and expanding unicode characters back to latex +# commands. +# See also: Completer.backslash_combining_completions +# c.IPCompleter.backslash_combining_completions = True + +## Enable debug for the Completer. Mostly print extra information for +# experimental jedi integration. +# See also: Completer.debug +# c.IPCompleter.debug = False + +## List of matchers to disable. +# +# The list should contain matcher identifiers (see +# :any:`completion_matcher`). +# Default: [] +# c.IPCompleter.disable_matchers = [] + +## Policy for code evaluation under completion. +# See also: Completer.evaluation +# c.IPCompleter.evaluation = 'limited' + +## Activate greedy completion. +# See also: Completer.greedy +# c.IPCompleter.greedy = False + +## Experimental: restrict time (in milliseconds) during which Jedi can compute +# types. +# See also: Completer.jedi_compute_type_timeout +# c.IPCompleter.jedi_compute_type_timeout = 400 + +## DEPRECATED as of version 5.0. +# +# Instruct the completer to use __all__ for the completion +# +# Specifically, when completing on ``object.``. +# +# When True: only those names in obj.__all__ will be included. +# +# When False [default]: the __all__ attribute is ignored +# Default: False +# c.IPCompleter.limit_to__all__ = False + +## Whether to merge completion results into a single list +# +# If False, only the completion results from the first non-empty +# completer will be returned. +# +# As of version 8.6.0, setting the value to ``False`` is an alias for: +# ``IPCompleter.suppress_competing_matchers = True.``. +# Default: True +# c.IPCompleter.merge_completions = True + +## Instruct the completer to omit private method names +# +# Specifically, when completing on ``object.``. +# +# When 2 [default]: all names that start with '_' will be excluded. +# +# When 1: all 'magic' names (``__foo__``) will be excluded. +# +# When 0: nothing will be excluded. +# Choices: any of [0, 1, 2] +# Default: 2 +# c.IPCompleter.omit__names = 2 + +## If True, emit profiling data for completion subsystem using cProfile. +# Default: False +# c.IPCompleter.profile_completions = False + +## Template for path at which to output profile data for completions. +# Default: '.completion_profiles' +# c.IPCompleter.profiler_output_dir = '.completion_profiles' + +## Whether to suppress completions from other *Matchers*. +# +# When set to ``None`` (default) the matchers will attempt to auto-detect +# whether suppression of other matchers is desirable. For example, at the +# beginning of a line followed by `%` we expect a magic completion to be the +# only applicable option, and after ``my_dict['`` we usually expect a completion +# with an existing dictionary key. +# +# If you want to disable this heuristic and see completions from all matchers, +# set ``IPCompleter.suppress_competing_matchers = False``. To disable the +# heuristic for specific matchers provide a dictionary mapping: +# ``IPCompleter.suppress_competing_matchers = {'IPCompleter.dict_key_matcher': +# False}``. +# +# Set ``IPCompleter.suppress_competing_matchers = True`` to limit completions to +# the set of matchers with the highest priority; this is equivalent to +# ``IPCompleter.merge_completions`` and can be beneficial for performance, but +# will sometimes omit relevant candidates from matchers further down the +# priority list. +# Default: None +# c.IPCompleter.suppress_competing_matchers = None + +## Experimental: Use Jedi to generate autocompletions. Default to True if jedi is +# installed. +# See also: Completer.use_jedi +# c.IPCompleter.use_jedi = True + +#------------------------------------------------------------------------------ +# ScriptMagics(Magics) configuration +#------------------------------------------------------------------------------ +## Magics for talking to scripts +# +# This defines a base `%%script` cell magic for running a cell +# with a program in a subprocess, and registers a few top-level +# magics that call %%script with common interpreters. + +## Extra script cell magics to define +# +# This generates simple wrappers of `%%script foo` as `%%foo`. +# +# If you want to add script magics that aren't on your path, +# specify them in script_paths +# Default: [] +# c.ScriptMagics.script_magics = [] + +## Dict mapping short 'ruby' names to full paths, such as '/opt/secret/bin/ruby' +# +# Only necessary for items in script_magics where the default path will not +# find the right interpreter. +# Default: {} +# c.ScriptMagics.script_paths = {} + +#------------------------------------------------------------------------------ +# LoggingMagics(Magics) configuration +#------------------------------------------------------------------------------ +## Magics related to all logging machinery. + +## Suppress output of log state when logging is enabled +# Default: False +# c.LoggingMagics.quiet = False + +#------------------------------------------------------------------------------ +# StoreMagics(Magics) configuration +#------------------------------------------------------------------------------ +## Lightweight persistence for python variables. +# +# Provides the %store magic. + +## If True, any %store-d variables will be automatically restored +# when IPython starts. +# Default: False +# c.StoreMagics.autorestore = False diff --git a/jupyter/jupyter_console_config.py b/jupyter/jupyter_console_config.py index 5e59ae9..9b82add 100644 --- a/jupyter/jupyter_console_config.py +++ b/jupyter/jupyter_console_config.py @@ -1,4 +1,5 @@ # Configuration file for jupyter-console. +# see: https://jupyter-console.readthedocs.io/en/latest/config_options.html #------------------------------------------------------------------------------ # JupyterConsoleApp configuration @@ -15,9 +16,6 @@ # ZMQTerminalIPythonApp configuration #------------------------------------------------------------------------------ -# Configure matplotlib for interactive use with the default matplotlib backend. -c.InteractiveShellApp.matplotlib = 'tk' - # Set to confirm when you try to exit IPython with an EOF (Control-D in Unix, # Control-Z/Enter in Windows). By typing 'exit' or 'quit', you can force a # direct exit without any confirmation. @@ -38,6 +36,9 @@ # Shortcut style to use at the prompt. 'vi' or 'emacs'. c.ZMQTerminalInteractiveShell.editing_mode = 'vi' +# Add shortcuts from 'emacs' insert mode to 'vi' insert mode. +c.ZMQInteractiveShell.emacs_bindings_in_vi_insert_mode = True + # Whether to include output from clients other than this one sharing the same # kernel. # diff --git a/nnn/plugins/preview-tui b/nnn/plugins/preview-tui index 15ea877..99aec16 100755 --- a/nnn/plugins/preview-tui +++ b/nnn/plugins/preview-tui @@ -1,18 +1,19 @@ -#!/usr/bin/env sh +#!/usr/bin/env bash # Description: Terminal based file previewer # # Note: This plugin needs a "NNN_FIFO" to work. See man. # # Dependencies: -# - Supports 5 independent methods to preview with: +# - Supports 6 independent methods to preview with: # - tmux (>=3.0), or # - kitty with allow_remote_control and listen_on set in kitty.conf, or +# - wezterm (https://wezfurlong.org/wezterm), or # - QuickLook on WSL (https://github.com/QL-Win/QuickLook), or # - Windows Terminal (https://github.com/Microsoft/Terminal | https://aka.ms/terminal) with WSL, or -# - $TERMINAL set to a terminal (it's xterm by default). -# - less or $PAGER -# - tree or exa or ls +# - $NNN_TERMINAL set to a terminal (it's xterm by default). +# - less or $NNN_PAGER +# - tree or exa/eza or (GNU) ls # - mediainfo or file # - mktemp # - unzip @@ -20,24 +21,30 @@ # - man # - optional: bsdtar or atool for additional archive preview # - optional: bat for code syntax highlighting -# - optional: ueberzug, kitty terminal, viu or catimg for images -# - optional: convert(ImageMagick) for playing gif preview +# - optional: ueberzug, kitty terminal, wezterm terminal, img2sixel, viu, catimg, timg or chafa for images +# - optional: convert(ImageMagick) for playing gif preview (mandatory for kitty image previews) +# - optional: mpv for gif and video +# Also requires a terminal supporting the sixel (https://www.arewesixelyet.com/) +# or kitty (https://sw.kovidgoyal.net/kitty/graphics-protocol) video_output backends. +# Requires tmux compiled with `./configure --enable-sixel` if used. # - optional: ffmpegthumbnailer for video thumbnails (https://github.com/dirkvdb/ffmpegthumbnailer) # - optional: ffmpeg for audio thumbnails # - optional: libreoffce for opendocument/officedocument preview # - optional: pdftoppm(poppler) for pdf thumbnails # - optional: gnome-epub-thumbnailer for epub thumbnails (https://gitlab.gnome.org/GNOME/gnome-epub-thumbnailer) # - optional: fontpreview for font preview (https://github.com/sdushantha/fontpreview) +# - optional: djvulibre for djvu # - optional: glow or lowdown for markdown # - optional: w3m or lynx or elinks for html -# - optional: set/export ICONLOOKUP as 1 to enable file icons in front of directory previews with .iconlookup -# Icons and colors are configureable in .iconlookup +# - optional: set/export NNN_ICONLOOKUP as 1 to enable file icons in front of directory previews with .iconlookup +# Icons and colors are configurable in .iconlookup # - optional: scope.sh file viewer from ranger. # 1. drop scope.sh executable in $PATH -# 2. set/export $USE_SCOPE as 1 +# 2. set/export $NNN_SCOPE as 1 # - optional: pistol file viewer (https://github.com/doronbehar/pistol). # 1. install pistol -# 2. set/export $USE_PISTOL as 1 +# 2. set/export $NNN_PISTOL as 1 +# - optional: librsvg for rsvg-convert # # Usage: # You need to set a NNN_FIFO path and a key for the plugin with NNN_PLUG, @@ -57,100 +64,157 @@ # # The previews will be shown in a tmux split. If that isn't possible, it # will try to use a kitty terminal split. And as a final fallback, a -# different terminal window will be used ($TERMINAL). +# different terminal window will be used ($NNN_TERMINAL). # -# Tmux and kitty users can configure $SPLIT to either "h" or "v" to set a -# 'h'orizontal split or a 'v'ertical split (as in, the line that splits the -# windows will be horizontal or vertical). +# Kitty users need something similar to the following in their kitty.conf: +# - `allow_remote_control yes` +# - `listen_on unix:$TMPDIR/kitty` +# - `enabled_layouts splits` (optional) +# With ImageMagick installed, this terminal can use the icat kitten to display images. +# Refer to kitty documentation for further details. # -# Kitty users need `allow_remote_control` set to `yes`, and `listen_on` set -# to e.g. "unix:$TMPDIR/kitty". To customize the window split, `enabled_layouts` -# has to be set to `all` or `splits` (the former is the default value). -# This terminal is also able to show images without extra dependencies. +# Users with both tmux and kitty can leverage image previews inside tmux with kitty's icat kitten +# - setup kitty as stated above +# - tmux >= v3.3a required +# - add the following to your tmux.conf: +# - `set -g allow-passthrough on` # -# Iterm2 users are recommended to use viu to view images without getting pixelated. +# Wezterm should work out of the box. If `NNN_PREVIEWIMGPROG` is not specified it will use +# built in iTerm2 image protocol. +# +# Note that GNU ls is used for its `--group-directories-first` flag. +# On MacOS this may be installed with `brew install coreutils`, or the flag can be removed. +# iTerm2 users are recommended to use viu to view images without getting pixelated. # # Windows Terminal users can set "Profile termination behavior" under "Profile > Advanced" settings -# to automaticaly close pane on quit when exit code is 0. +# to automatically close pane on quit when exit code is 0. +# +# When specifying a different terminal, additional arguments are supported. In particular, you can +# append a specific title to the terminal and set it to "nofocus" in your WM config. +# E.g for alacritty and i3, you can set $NNN_TERMINAL to 'alacritty --title preview-tui' and add +# 'no_focus [title="preview-tui"]' to your i3 config file. # -# Shell: POSIX compliant -# Authors: Todd Yamakawa, Léo Villeveygoux, @Recidiviste, Mario Ortiz Manero, Luuk van Baal, @WanderLanz +# Shell: Bash (for environment manipulation through arrays) +# Authors: Todd Yamakawa, Léo Villeveygoux, @Recidiviste, Mario Ortiz Manero, Luuk van Baal, @WanderLanz, @flipflop133 -#SPLIT="$SPLIT" # you can set a permanent split here -#TERMINAL="$TERMINAL" # same goes for the terminal -USE_SCOPE="${USE_SCOPE:-0}" -USE_PISTOL="${USE_PISTOL:-0}" -ICONLOOKUP="${ICONLOOKUP:-0}" -PAGER="${PAGER:-less -P?n -R}" -TMPDIR="${TMPDIR:-/tmp}" -BAT_STYLE="${BAT_STYLE:-plain}" -BAT_THEME="${BAT_THEME:-ansi}" -# Consider setting NNN_PREVIEWDIR to $XDG_CACHE_HOME/nnn/previews if you want to keep previews on disk between reboots -NNN_PREVIEWDIR="${NNN_PREVIEWDIR:-$TMPDIR/nnn/previews}" -NNN_PREVIEWWIDTH="${NNN_PREVIEWWIDTH:-1920}" -NNN_PREVIEWHEIGHT="${NNN_PREVIEWHEIGHT:-1080}" -NNN_PARENT="${NNN_FIFO#*.}" -[ "$NNN_PARENT" -eq "$NNN_PARENT" ] 2>/dev/null || NNN_PARENT="" -FIFOPID="$TMPDIR/nnn-preview-tui-fifopid.$NNN_PARENT" -PREVIEWPID="$TMPDIR/nnn-preview-tui-pagerpid.$NNN_PARENT" -CURSEL="$TMPDIR/nnn-preview-tui-selection.$NNN_PARENT" -FIFO_UEBERZUG="$TMPDIR/nnn-preview-tui-ueberzug-fifo.$NNN_PARENT" +# Configurable environment variables: +NNN_SPLIT=${NNN_SPLIT:-} # permanent split direction +NNN_TERMINAL=${NNN_TERMINAL:-} # external terminal to be used +# NNN_TERMINAL=${NNN_TERMINAL:-} # external terminal to be used +NNN_SPLITSIZE=${NNN_SPLITSIZE:-50} # previewer split size percentage +TMPDIR=${TMPDIR:-/tmp} # location of temporary files +ENVVARS=( + "NNN_SCOPE=${NNN_SCOPE:-0}" # use scope + "NNN_PISTOL=${NNN_PISTOL:-0}" # use pistol + "NNN_ICONLOOKUP=${NNN_ICONLOOKUP:-0}" # use .iconlookup + "NNN_PAGER=${NNN_PAGER:-less -R -C}" # pager options + "NNN_BATTHEME=${NNN_BATTHEME:-ansi}" # bat theme + "NNN_BATSTYLE=${NNN_BATSTYLE:-numbers}" # bat style + "NNN_PREVIEWWIDTH=${NNN_PREVIEWWIDTH:-1920}" # width of generated preview images + "NNN_PREVIEWHEIGHT=${NNN_PREVIEWHEIGHT:-1080}" # height of generated preview images + "NNN_PREVIEWDIR=${NNN_PREVIEWDIR:-$TMPDIR/nnn/previews}" # location of generated preview images + "NNN_PREVIEWIMGPROG=${NNN_PREVIEWIMGPROG:-}" # command used to preview images + "NNN_PREVIEWVIDEO=${NNN_PREVIEWVIDEO:-}" # mpv backend used to preview video +) +# Non-configurable environment variables +NNN_PARENT=${NNN_FIFO#*.} +[ "$NNN_PARENT" -eq "$NNN_PARENT" ] 2>/dev/null || NNN_PARENT="" # Make empty if non-numeric +ENVVARS+=( + "PWD=$PWD" + "PATH=$PATH" + "LSCOLORS=$LSCOLORS" + "LS_COLORS=$LS_COLORS" + "NNN_FIFO=$NNN_FIFO" + "FIFOPID=$TMPDIR/nnn-preview-tui-fifopid.$NNN_PARENT" + "FIFOPATH=$TMPDIR/nnn-preview-tui-fifo.$NNN_PARENT" + "PREVIEWPID=$TMPDIR/nnn-preview-tui-previewpid.$NNN_PARENT" + "CURSEL=$TMPDIR/nnn-preview-tui-selection.$NNN_PARENT" + "FIFO_UEBERZUG=$TMPDIR/nnn-preview-tui-ueberzug-fifo.$NNN_PARENT" + "POSOFFSET=$TMPDIR/nnn-preview-tui-posoffset" +) -start_preview() { - [ "$PAGER" = "most" ] && PAGER="less -R" +trap '' PIPE +exists() { type "$1" >/dev/null 2>&1 ;} +pkill() { command pkill "$@" >/dev/null 2>&1 ;} +prompt() { clear; printf "%b" "$@"; cfg=$(stty -g); stty raw -echo; head -c 1; stty "$cfg" ;} +pidkill() { + if [ -f "$1" ]; then + PID="$(cat "$1" 2>/dev/null)" || return 1 + kill "$PID" >/dev/null 2>&1 + RET=$? + wait "$PID" 2>/dev/null + return $RET + fi + return 1 +} +start_preview() { if [ -e "${TMUX%%,*}" ] && tmux -V | grep -q '[ -][3456789]\.'; then - TERMINAL=tmux + NNN_TERMINAL=tmux + exists mpv && tmux display -p '#{client_termfeatures}' | grep -q 'sixel' && ENVVARS+=("NNN_PREVIEWVIDEO=sixel") elif [ -n "$KITTY_LISTEN_ON" ]; then - TERMINAL=kitty - elif [ -z "$TERMINAL" ] && [ "$TERM_PROGRAM" = "iTerm.app" ]; then - TERMINAL=iterm + NNN_TERMINAL=kitty + exists mpv && ENVVARS+=("NNN_PREVIEWVIDEO=kitty") + elif [ -z "$NNN_TERMINAL" ] && [ "$TERM_PROGRAM" = "WezTerm" ]; then + # https://superuser.com/questions/1749781/how-can-i-check-if-the-environment-is-wsl-from-a-shell-script + if [ -f /proc/sys/fs/binfmt_misc/WSLInterop ]; then + NNN_TERMINAL=wezterm.exe + else + NNN_TERMINAL=wezterm + fi + exists mpv && ENVVARS+=("NNN_PREVIEWVIDEO=kitty") + elif [ -z "$NNN_TERMINAL" ] && [ "$TERM_PROGRAM" = "iTerm.app" ]; then + NNN_TERMINAL=iterm + exists mpv && ENVVARS+=("NNN_PREVIEWVIDEO=sixel") elif [ -n "$WT_SESSION" ]; then - TERMINAL=winterm + NNN_TERMINAL=winterm else - TERMINAL="${TERMINAL:-xterm}" + NNN_TERMINAL="${NNN_TERMINAL:-xterm}" fi - if [ -z "$SPLIT" ] && [ $(($(tput lines <"$TTY") * 2)) -gt "$(tput cols <"$TTY")" ]; then - SPLIT='h' - elif [ "$SPLIT" != 'h' ]; then - SPLIT='v' + if [ -z "$NNN_SPLIT" ] && [ $(($(tput lines) * 2)) -gt "$(tput cols)" ]; then + NNN_SPLIT='h' + elif [ "$NNN_SPLIT" != 'h' ]; then + NNN_SPLIT='v' fi - case "$TERMINAL" in + ENVVARS+=("NNN_TERMINAL=$NNN_TERMINAL" "NNN_SPLIT=$NNN_SPLIT" "QLPATH=$2" "PREVIEW_MODE=1") + case "$NNN_TERMINAL" in + iterm|winterm) # has to run in separate shell command: escape + ENVVARS=("${ENVVARS[@]/#/\\\"}") + ENVVARS=("${ENVVARS[@]/%/\\\"}") + command="$SHELL -c 'env ${ENVVARS[*]} \\\"$0\\\" \\\"$1\\\"'" ;; + # wezterm.exe) + # ENVVARS=("${ENVVARS[@]/#/\\\"}") + # ENVVARS=("${ENVVARS[@]/%/\\\"}") + # echo ${ENVVARS[*]} >&2 + # command="--cd \"$PWD\" -- env ${ENVVARS[*]} \"$0\" \"$1\"" ;; + # echo ${ENVVARS[@]} >&2 + # command="--cd \"$PWD\" -- env ${ENVVARS[@]} less output.txt" ;; + esac + + case "$NNN_TERMINAL" in tmux) # tmux splits are inverted - if [ "$SPLIT" = "v" ]; then DSPLIT="h"; else DSPLIT="v"; fi - tmux split-window -e "NNN_FIFO=$NNN_FIFO" -e "PREVIEW_MODE=1" -e TTY="$TTY" \ - -e "CURSEL=$CURSEL" -e "TMPDIR=$TMPDIR" -e "FIFOPID=$FIFOPID" \ - -e "BAT_STYLE=$BAT_STYLE" -e "BAT_THEME=$BAT_THEME" -e "PREVIEWPID=$PREVIEWPID" \ - -e "PAGER=$PAGER" -e "ICONLOOKUP=$ICONLOOKUP" -e "NNN_PREVIEWWIDTH=$NNN_PREVIEWWIDTH" \ - -e "USE_SCOPE=$USE_SCOPE" -e "SPLIT=$SPLIT" -e "USE_PISTOL=$USE_PISTOL" \ - -e "NNN_PREVIEWDIR=$NNN_PREVIEWDIR" -e "NNN_PREVIEWHEIGHT=$NNN_PREVIEWHEIGHT" \ - -e "FIFO_UEBERZUG=$FIFO_UEBERZUG" -e "QLPATH=$2" -d"$DSPLIT" "$0" "$1" ;; + ENVVARS=("${ENVVARS[@]/#/-e}") + if [ "$NNN_SPLIT" = "v" ]; then split="h"; else split="v"; fi + tmux split-window -l"$NNN_SPLITSIZE"% "${ENVVARS[@]}" -d"$split" -p"$NNN_SPLITSIZE" "$0" "$1" ;; kitty) # Setting the layout for the new window. It will be restored after the script ends. + ENVVARS=("${ENVVARS[@]/#/--env=}") kitty @ goto-layout splits - # Trying to use kitty's integrated window management as the split window. All - # environmental variables that will be used in the new window must be explicitly passed. - kitty @ launch --no-response --title "nnn preview" --keep-focus \ - --cwd current --env "PATH=$PATH" --env "NNN_FIFO=$NNN_FIFO" \ - --env "PREVIEW_MODE=1" --env "PAGER=$PAGER" --env "TMPDIR=$TMPDIR" \ - --env "USE_SCOPE=$USE_SCOPE" --env "SPLIT=$SPLIT" --env "TERMINAL=$TERMINAL"\ - --env "PREVIEWPID=$PREVIEWPID" --env "FIFO_UEBERZUG=$FIFO_UEBERZUG" \ - --env "ICONLOOKUP=$ICONLOOKUP" --env "NNN_PREVIEWHEIGHT=$NNN_PREVIEWHEIGHT" \ - --env "NNN_PREVIEWWIDTH=$NNN_PREVIEWWIDTH" --env "NNN_PREVIEWDIR=$NNN_PREVIEWDIR" \ - --env "USE_PISTOL=$USE_PISTOL" --env "BAT_STYLE=$BAT_STYLE" \ - --env "BAT_THEME=$BAT_THEME" --env "FIFOPID=$FIFOPID" --env TTY="$TTY" \ - --env "CURSEL=$CURSEL" --location "${SPLIT}split" "$0" "$1" ;; + # Trying to use kitty's integrated window management as the split window. + kitty @ launch --no-response --title "preview-tui" --keep-focus \ + --cwd "$PWD" "${ENVVARS[@]}" --location "${NNN_SPLIT}split" "$0" "$1" ;; + wezterm) + export "${ENVVARS[@]}" + if [ "$NNN_SPLIT" = "v" ]; then split="--horizontal"; else split="--bottom"; fi + wezterm cli split-pane --cwd "$PWD" $split --percent "$NNN_SPLITSIZE" "$0" "$1" >/dev/null + wezterm cli activate-pane-direction Prev ;; + wezterm.exe) + if [ "$NNN_SPLIT" = "v" ]; then split="--horizontal"; else split="--bottom"; fi + wezterm.exe cli split-pane $split --percent "$NNN_SPLITSIZE" "wsl.exe" --cd "$PWD" -e env "${ENVVARS[@]}" "$0" "$1" >/dev/null + wezterm.exe cli activate-pane-direction Prev ;; iterm) - command="$SHELL -c 'cd $PWD; \ - PATH=\\\"$PATH\\\" NNN_FIFO=\\\"$NNN_FIFO\\\" PREVIEW_MODE=1 PAGER=\\\"$PAGER\\\" \ - USE_SCOPE=\\\"$USE_SCOPE\\\" SPLIT=\\\"$SPLIT\\\" TERMINAL=\\\"$TERMINAL\\\" \ - PREVIEWPID=\\\"$PREVIEWPID\\\" CURSEL=\\\"$CURSEL\\\" TMPDIR=\\\"$TMPDIR\\\" \ - ICONLOOKUP=\\\"$ICONLOOKUP\\\" NNN_PREVIEWHEIGHT=\\\"$NNN_PREVIEWHEIGHT\\\" \ - NNN_PREVIEWWIDTH=\\\"$NNN_PREVIEWWIDTH\\\" NNN_PREVIEWDIR=\\\"$NNN_PREVIEWDIR\\\" \ - USE_PISTOL=\\\"$USE_PISTOL\\\" BAT_STYLE=\\\"$BAT_STYLE\\\" TTY=\\\"$TTY\\\" \ - BAT_THEME=\\\"$BAT_THEME\\\" FIFOPID=\\\"$FIFOPID\\\" \\\"$0\\\" \\\"$1\\\"'" - if [ "$SPLIT" = "h" ]; then split="horizontally"; else split="vertically"; fi + if [ "$NNN_SPLIT" = "h" ]; then split="horizontally"; else split="vertically"; fi osascript <<-EOF tell application "iTerm" tell current session of current window @@ -160,33 +224,27 @@ start_preview() { EOF ;; winterm) - if [ "$SPLIT" = "h" ]; then split="H"; else split="V"; fi - cmd.exe /c wt -w 0 sp -$split bash -c "cd $PWD \; PATH='$PATH' NNN_FIFO=$NNN_FIFO \ - PREVIEW_MODE=1 TTY=$TTY CURSEL=$CURSEL TMPDIR=$TMPDIR FIFOPID=$FIFOPID \ - BAT_STYLE=$BAT_STYLE BAT_THEME=$BAT_THEME PREVIEWPID=$PREVIEWPID \ - PAGER='$PAGER' ICONLOOKUP=$ICONLOOKUP NNN_PREVIEWWIDTH=$NNN_PREVIEWWIDTH \ - USE_SCOPE=$USE_SCOPE SPLIT=$SPLIT USE_PISTOL=$USE_PISTOL \ - NNN_PREVIEWDIR=$NNN_PREVIEWDIR NNN_PREVIEWHEIGHT=$NNN_PREVIEWHEIGHT \ - FIFO_UEBERZUG=$FIFO_UEBERZUG QLPATH=$2 $0 $1" \; -w 0 mf previous - ;; + if [ "$NNN_SPLIT" = "h" ]; then split="H"; else split="V"; fi + wt -w 0 sp -$split -s"0.$NNN_SPLITSIZE" "$command" \; -w 0 mf previous 2>/dev/null ;; *) if [ -n "$2" ]; then - QUICKLOOK=1 QLPATH="$2" PREVIEW_MODE=1 "$0" "$1" & + env "${ENVVARS[@]}" QUICKLOOK=1 "$0" "$1" & else - PREVIEWPID="$PREVIEWPID" CURSEL="$CURSEL" PREVIEW_MODE=1 TTY="$TTY" \ - FIFOPID="$FIFOPID" FIFO_UEBERZUG="$FIFO_UEBERZUG" $TERMINAL -e "$0" "$1" & + # shellcheck disable=SC2086 # (allow arguments) + env "${ENVVARS[@]}" $NNN_TERMINAL -e "$0" "$1" & fi ;; esac -} >/dev/null 2>&1 +} toggle_preview() { + export "${ENVVARS[@]}" if exists QuickLook.exe; then QLPATH="QuickLook.exe" elif exists Bridge.exe; then QLPATH="Bridge.exe" fi - if kill "$(cat "$FIFOPID")"; then + if pidkill "$FIFOPID"; then [ -p "$NNN_PPIPE" ] && printf "0" > "$NNN_PPIPE" - kill "$(cat "$PREVIEWPID")" + pidkill "$PREVIEWPID" pkill -f "tail --follow $FIFO_UEBERZUG" if [ -n "$QLPATH" ] && stat "$1"; then f="$(wslpath -w "$1")" && "$QLPATH" "$f" & @@ -195,39 +253,34 @@ toggle_preview() { [ -p "$NNN_PPIPE" ] && printf "1" > "$NNN_PPIPE" start_preview "$1" "$QLPATH" fi -} >/dev/null 2>&1 - -exists() { - type "$1" >/dev/null } fifo_pager() { cmd="$1" shift - # We use a FIFO to access $PAGER PID in jobs control - tmpfifopath="$TMPDIR/nnn-preview-tui-fifo.$$" - mkfifo "$tmpfifopath" || return + # We use a FIFO to access $NNN_PAGER PID in jobs control + mkfifo "$FIFOPATH" || return - $PAGER < "$tmpfifopath" & + $NNN_PAGER < "$FIFOPATH" & printf "%s" "$!" > "$PREVIEWPID" ( - exec > "$tmpfifopath" + exec > "$FIFOPATH" if [ "$cmd" = "pager" ]; then if exists bat; then - bat --terminal-width="$(tput cols <"$TTY")" --decorations=always --color=always \ - --paging=never --style="$BAT_STYLE" --theme="$BAT_THEME" "$@" & + bat --terminal-width="$cols" --decorations=always --color=always \ + --paging=never --style="$NNN_BATSTYLE" --theme="$NNN_BATTHEME" "$@" & else - $PAGER "$@" & + $NNN_PAGER "$@" & fi else "$cmd" "$@" & fi ) - rm "$tmpfifopath" -} 2>/dev/null + rm -- "$FIFOPATH" +} # Binary file: show file info inside the pager print_bin_info() { @@ -237,17 +290,18 @@ print_bin_info() { else file -b "$1" fi -} 2>/dev/null +} handle_mime() { case "$2" in image/jpeg) image_preview "$cols" "$lines" "$1" ;; image/gif) generate_preview "$cols" "$lines" "$1" "gif" ;; + image/vnd.djvu) generate_preview "$cols" "$lines" "$1" "djvu" ;; image/*) generate_preview "$cols" "$lines" "$1" "image" ;; video/*) generate_preview "$cols" "$lines" "$1" "video" ;; audio/*) generate_preview "$cols" "$lines" "$1" "audio" ;; application/font*|application/*opentype|font/*) generate_preview "$cols" "$lines" "$1" "font" ;; - */*office*|*/*document*) generate_preview "$cols" "$lines" "$1" "office" ;; + */*office*|*/*document*|*/*msword|*/*ms-excel) generate_preview "$cols" "$lines" "$1" "office" ;; application/zip) fifo_pager unzip -l "$1" ;; text/troff) if exists man; then @@ -288,13 +342,6 @@ handle_ext() { elif exists bsdtar; then fifo_pager bsdtar -tvf "$1" fi ;; - ipynb) - if exists jupyter; then - fifo_pager eval "jupyter nbconvert --stdout --to markdown --MarkdownExporter.exclude_output=True \"$1\" | pygmentize -l md" - fi ;; - textbundle|orgbundle) - fifo_pager eval "echo HERE" - ;; *) if [ "$3" = "bin" ]; then fifo_pager print_bin_info "$1" else @@ -306,13 +353,13 @@ handle_ext() { preview_file() { clear # Trying to use pistol if it's available. - if [ "$USE_PISTOL" -ne 0 ] && exists pistol; then + if [ "$NNN_PISTOL" -ne 0 ] && exists pistol; then fifo_pager pistol "$1" return fi # Trying to use scope.sh if it's available. - if [ "$USE_SCOPE" -ne 0 ] && exists scope.sh; then + if [ "$NNN_SCOPE" -ne 0 ] && exists scope.sh; then fifo_pager scope.sh "$1" "$cols" "$lines" "$(mktemp -d)" "True" return fi @@ -328,55 +375,45 @@ preview_file() { mimetype="$(file -bL --mime-type -- "$1")" ext="${1##*.}" [ -n "$ext" ] && ext="$(printf "%s" "${ext}" | tr '[:upper:]' '[:lower:]')" - lines=$(tput lines <"$TTY") - cols=$(tput cols <"$TTY") + lines=$(tput lines) + cols=$(tput cols) # Otherwise, falling back to the defaults. if [ -d "$1" ]; then cd "$1" || return - if [ "$ext" = "textbundle" ] || [ "$ext" = "orgbundle" ]; then - for ext in org md markdown adoc; do - if [ -e "text.$ext" ]; then - preview_file "text.$ext" - break - fi - done - elif [ "$ICONLOOKUP" -ne 0 ] && [ -f "$(dirname "$0")"/.iconlookup ]; then - [ "$SPLIT" = v ] && BSTR="\n" + if [ "$NNN_ICONLOOKUP" -ne 0 ] && [ -f "$(dirname "$0")"/.iconlookup ]; then + [ "$NNN_SPLIT" = v ] && BSTR="\n" # shellcheck disable=SC2012 ls -F --group-directories-first | head -n "$((lines - 3))" | "$(dirname "$0")"/.iconlookup -l "$cols" -B "$BSTR" -b " " elif exists tree; then fifo_pager tree --filelimit "$(find . -maxdepth 1 | wc -l)" -L 3 -C -F --dirsfirst --noreport elif exists exa; then - exa -G --group-directories-first --colour=always + fifo_pager exa -T --group-directories-first --colour=always -L 3 + elif exists eza; then # eza is a community fork of exa (exa is unmaintained) + fifo_pager eza -T --group-directories-first --colour=always -L 3 else fifo_pager ls -F --group-directories-first --color=always fi + cd .. elif [ "${encoding#*)}" = "binary" ]; then handle_mime "$1" "$mimetype" "$ext" "bin" else handle_mime "$1" "$mimetype" "$ext" fi -} 2>/dev/null +} generate_preview() { if [ -n "$QLPATH" ] && stat "$3"; then f="$(wslpath -w "$3")" && "$QLPATH" "$f" & - elif [ ! -f "$NNN_PREVIEWDIR/$3.(jpg|png)" ] || [ -n "$(find -L "$3" -newer "$NNN_PREVIEWDIR/$3.(jpg|png)")" ]; then + elif [ -n "$NNN_PREVIEWVIDEO" ] && [[ "$4" == +(gif|video) ]]; then + [ "$4" = "video" ] && args=(--start=10% --length=4) || args=() + video_preview "$1" "$2" "$3" "${args[@]}" && return + elif [ ! -f "$NNN_PREVIEWDIR/$3.jpg" ] || [ -n "$(find -L "$3" -newer "$NNN_PREVIEWDIR/$3.jpg")" ]; then mkdir -p "$NNN_PREVIEWDIR/${3%/*}" case $4 in audio) ffmpeg -i "$3" -filter_complex "scale=iw*min(1\,min($NNN_PREVIEWWIDTH/iw\,ih)):-1" "$NNN_PREVIEWDIR/$3.jpg" -y ;; epub) gnome-epub-thumbnailer "$3" "$NNN_PREVIEWDIR/$3.jpg" ;; - font) - # convert -size 532X365 xc:"#ffffff" \ - # -gravity center \ - # -pointsize 42 \ - # -fill "#000000" \ - # -font "$3" \ - # -annotate +0+0 "ABCDEFGHIJKLM\nNOPQRSTUVWXYZ\nabcdefghijklm\nnopqrstuvwxyz\n1234567890\n!@$\%(){}[]" \ - # -flatten "$NNN_PREVIEWDIR/$3.png" - hb-view -o "$NNN_PREVIEWDIR/$3.png" "$3" "FooBar" - ;; + font) fontpreview -i "$3" -o "$NNN_PREVIEWDIR/$3.jpg" ;; gif) if [ -p "$FIFO_UEBERZUG" ] && exists convert; then frameprefix="$NNN_PREVIEWDIR/$3/${3##*/}" if [ ! -d "$NNN_PREVIEWDIR/$3" ]; then @@ -394,51 +431,71 @@ generate_preview() { done & printf "%s" "$!" > "$PREVIEWPID" return + elif [ -n "$NNN_PREVIEWVIDEO" ]; then + video_preview "$1" "$2" "$3" && return else - exec >/dev/tty - image_preview "$1" "$2" "$3" - return + image_preview "$1" "$2" "$3" && return fi ;; - image) if exists convert; then + image) if exists rsvg-convert && [[ "${3##*.}" == "svg" ]]; then + rsvg-convert -a -w "$NNN_PREVIEWWIDTH" -h "$NNN_PREVIEWHEIGHT" -f png -o "$NNN_PREVIEWDIR/$3.png" "$3" + elif exists convert; then convert "$3" -flatten -resize "$NNN_PREVIEWWIDTH"x"$NNN_PREVIEWHEIGHT"\> "$NNN_PREVIEWDIR/$3.jpg" else image_preview "$1" "$2" "$3" && return fi ;; office) libreoffice --convert-to jpg "$3" --outdir "$NNN_PREVIEWDIR/${3%/*}" filename="$(printf "%s" "${3##*/}" | cut -d. -f1)" - mv "$NNN_PREVIEWDIR/${3%/*}/$filename.jpg" "$NNN_PREVIEWDIR/$3.jpg" ;; + mv -- "$NNN_PREVIEWDIR/${3%/*}/$filename.jpg" "$NNN_PREVIEWDIR/$3.jpg" ;; pdf) pdftoppm -jpeg -f 1 -singlefile "$3" "$NNN_PREVIEWDIR/$3" ;; - video) ffmpegthumbnailer -s0 -i "$3" -o "$NNN_PREVIEWDIR/$3.jpg" || rm "$NNN_PREVIEWDIR/$3.jpg" ;; + djvu) ddjvu -format=ppm -page=1 "$3" "$NNN_PREVIEWDIR/$3.jpg" ;; + video) video_preview "$1" "$2" "$3" && return ;; esac - fi >/dev/null + fi if [ -f "$NNN_PREVIEWDIR/$3.jpg" ]; then image_preview "$1" "$2" "$NNN_PREVIEWDIR/$3.jpg" - elif [ -f "$NNN_PREVIEWDIR/$3.png" ]; then + elif [[ "${3##*.}" == "svg" ]] && [ -f "$NNN_PREVIEWDIR/$3.png" ]; then image_preview "$1" "$2" "$NNN_PREVIEWDIR/$3.png" else fifo_pager print_bin_info "$3" fi -} 2>/dev/null +} >/dev/null 2>&1 image_preview() { clear - if [ "$TERMINAL" = "kitty" ]; then - # Kitty terminal users can use the native image preview method - kitty +kitten icat --silent --place "$1"x"$2"@0x0 --transfer-mode=stream --stdin=no "$3" & - elif exists ueberzug; then + exec >/dev/tty + if [ "$NNN_TERMINAL" = "kitty" ] && [[ "$NNN_PREVIEWIMGPROG" == +(|icat) ]]; then + kitty +kitten icat --silent --scale-up --place "$1"x"$2"@0x0 --transfer-mode=stream --stdin=no "$3" & + elif [ "$NNN_TERMINAL" = "tmux" ] && [[ -n "$KITTY_LISTEN_ON" ]] && [[ "$NNN_PREVIEWIMGPROG" == +(|icat) ]]; then + kitty +kitten icat --silent --scale-up --place "$(($1 - 1))x$(($2 - 1))"@0x0 --transfer-mode=memory --stdin=no "$3" & + elif [ "$NNN_TERMINAL" = "wezterm" ] && [[ "$NNN_PREVIEWIMGPROG" == +(|imgcat) ]]; then + wezterm imgcat "$3" & + elif exists ueberzug && [[ "$NNN_PREVIEWIMGPROG" == +(|ueberzug) ]]; then ueberzug_layer "$1" "$2" "$3" && return - elif exists catimg; then - catimg "$3" & - elif exists viu; then - viu -t "$3" & + elif [ "$NNN_TERMINAL" = "wezterm.exe" ] && exists "${NNN_PREVIEWIMGPROG%% *}"; then + $NNN_PREVIEWIMGPROG "$3" && return + elif exists "${NNN_PREVIEWIMGPROG%% *}"; then # can include command flags; only check first word + "$NNN_PREVIEWIMGPROG" "$3" & else fifo_pager print_bin_info "$3" && return fi printf "%s" "$!" > "$PREVIEWPID" -} 2>/dev/null +} + +video_preview() { + clear + exec >/dev/tty + if [ -n "$NNN_PREVIEWVIDEO" ]; then + mpv --no-config --really-quiet --vo="$NNN_PREVIEWVIDEO" --profile=sw-fast --loop-file --no-audio "$4" "$3" & + else + ffmpegthumbnailer -m -s0 -i "$3" -o "$NNN_PREVIEWDIR/$3.jpg" || rm -- "$NNN_PREVIEWDIR/$3.jpg" & + fi + printf "%s" "$!" > "$PREVIEWPID" +} ueberzug_layer() { - printf '{"action": "add", "identifier": "nnn_ueberzug", "x": 0, "y": 0, "width": "%d", "height": "%d", "scaler": "fit_contain", "path": "%s"}\n' "$1" "$2" "$3" > "$FIFO_UEBERZUG" + [ -f "$POSOFFSET" ] && read -r x y < "$POSOFFSET" + printf '{"action": "add", "identifier": "nnn_ueberzug", "x": %d, "y": %d, "width": "%d", "height": "%d", "scaler": "fit_contain", "path": "%s"}\n'\ + "${x:-0}" "${y:-0}" "$1" "$2" "$3" > "$FIFO_UEBERZUG" } ueberzug_remove() { @@ -447,18 +504,18 @@ ueberzug_remove() { winch_handler() { clear - kill "$(cat "$PREVIEWPID")" + pidkill "$PREVIEWPID" if [ -p "$FIFO_UEBERZUG" ]; then pkill -f "tail --follow $FIFO_UEBERZUG" tail --follow "$FIFO_UEBERZUG" | ueberzug layer --silent --parser json & fi preview_file "$(cat "$CURSEL")" -} 2>/dev/null +} preview_fifo() { while read -r selection; do if [ -n "$selection" ]; then - kill "$(cat "$PREVIEWPID")" + pidkill "$PREVIEWPID" [ -p "$FIFO_UEBERZUG" ] && ueberzug_remove [ "$selection" = "close" ] && break preview_file "$selection" @@ -467,33 +524,30 @@ preview_fifo() { done < "$NNN_FIFO" sleep 0.1 # make sure potential preview by winch_handler is killed pkill -P "$$" -} 2>/dev/null +} -if [ "$PREVIEW_MODE" ]; then - if [ "$TERMINAL" != "kitty" ] && exists ueberzug; then +if [ "$PREVIEW_MODE" -eq 1 ] 2>/dev/null; then + if exists ueberzug && [ "$NNN_TERMINAL" != "kitty" ] && [[ "$NNN_PREVIEWIMGPROG" == +(|ueberzug) ]]; then mkfifo "$FIFO_UEBERZUG" tail --follow "$FIFO_UEBERZUG" | ueberzug layer --silent --parser json & fi preview_file "$PWD/$1" - preview_fifo & + preview_fifo & WAITPID=$! printf "%s" "$!" > "$FIFOPID" printf "%s" "$PWD/$1" > "$CURSEL" - trap 'winch_handler; wait' WINCH - trap 'rm "$PREVIEWPID" "$CURSEL" "$FIFO_UEBERZUG" "$FIFOPID" 2>/dev/null' INT HUP EXIT - wait "$!" 2>/dev/null + trap 'winch_handler' WINCH + trap 'rm -- "$PREVIEWPID" "$CURSEL" "$FIFO_UEBERZUG" "$FIFOPID" "$POSOFFSET" 2>/dev/null' INT HUP EXIT + while kill -s 0 $WAITPID; do + wait $WAITPID 2>/dev/null + done exit 0 else if [ ! -r "$NNN_FIFO" ]; then - clear - printf "No FIFO available! (\$NNN_FIFO='%s')\nPlease read Usage in preview-tui." "$NNN_FIFO" - cfg=$(stty -g); stty raw -echo; head -c 1; stty "$cfg" + prompt "No FIFO available! (\$NNN_FIFO='$NNN_FIFO')\nPlease read Usage in '$0'." elif [ "$KITTY_WINDOW_ID" ] && [ -z "$TMUX" ] && [ -z "$KITTY_LISTEN_ON" ]; then - clear - printf "\$KITTY_LISTEN_ON not set!\nPlease read Usage in preview-tui." - cfg=$(stty -g); stty raw -echo; head -c 1; stty "$cfg" + prompt "\$KITTY_LISTEN_ON not set!\nPlease read Usage in '$0'." else - TTY="$(tty)" - TTY="$TTY" toggle_preview "$1" & + toggle_preview "$1" & fi fi diff --git a/nvim/init.lua b/nvim/init.lua index 3c0d342..658d143 100644 --- a/nvim/init.lua +++ b/nvim/init.lua @@ -1,369 +1,559 @@ -local package_root = vim.fn.stdpath('data')..'/site/pack' -local install_path = package_root .. '/packer/start/packer.nvim' -local compile_path = vim.fn.stdpath('config')..'/plugin/packer_compiled.lua' +local package_root = vim.fn.stdpath("data") .. "/site/pack" +local install_path = package_root .. "/packer/start/packer.nvim" +local compile_path = vim.fn.stdpath("config") .. "/plugin/packer_compiled.lua" if vim.fn.isdirectory(install_path) == 0 then - vim.fn.system({ 'git', 'clone', 'https://github.com/wbthomason/packer.nvim', install_path }) + vim.fn.system({ "git", "clone", "https://github.com/wbthomason/packer.nvim", install_path }) end --plugins {{{ local function load_plugins() + require("packer").startup({ + function(use) + -- development plugins + -- @param path string + -- @return string + -- https://github.com/aspeddro/dotfiles/blob/main/.config/nvim/lua/user/packages.lua + local here = function(path) + return vim.fn.expand("~/src/") .. path + end -require'packer'.startup {function (use) - - -- development plugins - -- @param path string - -- @return string - -- https://github.com/aspeddro/dotfiles/blob/main/.config/nvim/lua/user/packages.lua - local here = function(path) - return vim.fn.expand '~/src/' .. path - end - - ---packer {{{ - -- package management - use { 'wbthomason/packer.nvim' } - ---}}} - - ---mason {{{ - -- package manager for external dependencies - use { - 'williamboman/mason.nvim', - requires = { 'williamboman/mason-lspconfig.nvim' }, - config = function() - require'mason'.setup() - require'mason-lspconfig'.setup({ - ensure_installed = { 'vimls', 'html', 'julials', 'pyright', 'jsonls', - 'ltex', 'texlab', 'clangd', 'bashls', 'lua_ls', 'solargraph', - 'stylelint_lsp', 'beancount', 'typst_lsp', 'hoon_ls' } + ---packer {{{ + -- package management + use({ "wbthomason/packer.nvim" }) + ---}}} + + ---mason {{{ + -- package manager for external dependencies + use({ + "williamboman/mason.nvim", + requires = { + "mason-org/mason-registry", + "williamboman/mason-lspconfig.nvim", + "jay-babu/mason-null-ls.nvim" + }, + config = function() + require("mason").setup() + require("mason-lspconfig").setup({ + ensure_installed = { + "vimls", + "html", + "julials", + "jsonls", + "ltex", + "texlab", + "clangd", + "bashls", + "lua_ls", + "pyright", + "solargraph", + "stylelint_lsp", + "typst_lsp", + "ruff", + }, + }) + require("mason-null-ls").setup({ + ensure_installed = { "codespell", "stylua" }, + }) + end, }) + ---}}} + + ---plenary {{{ + -- lua utilities + use({ "nvim-lua/plenary.nvim" }) + ---}}} + + ---telescope {{{ + -- find, filter, preview, pick + use({ + "nvim-telescope/telescope.nvim", + requires = { "nvim-telescope/telescope-file-browser.nvim", "hrsh7th/nvim-cmp" }, + config = function() + local telescope = require("telescope") + local cmp = require("cmp") + + local actions = require("telescope.actions") + local finders = require("telescope.finders") + local action_state = require("telescope.actions.state") + local builtin = require("telescope.builtin") + local themes = require("telescope.themes") + + local function narrow_picker(prompt_bufnr) + local picker = action_state.get_current_picker(prompt_bufnr) + local manager = picker.manager + local results = {} + + if #picker:get_multi_selection() > 0 then + for _, entry in ipairs(picker:get_multi_selection()) do + table.insert(results, entry) + print(vim.inspect(entry)) + end + else + for entry in manager:iter() do + table.insert(results, entry) + end + end - end - } - ---}}} + local finder = finders.new_table({ + results = results, + entry_maker = function(entry) + return entry + end, + }) - ---plenary {{{ - -- lua utilities - use { 'nvim-lua/plenary.nvim' } - ---}}} + picker:refresh(finder, { reset_prompt = true }) + end - ---telescope {{{ - -- find, filter, preview, pick - use { - 'nvim-telescope/telescope.nvim', - requires = { 'nvim-telescope/telescope-file-browser.nvim' }, - config = function () - - local actions = require'telescope.actions' - local finders = require "telescope.finders" - local action_state = require "telescope.actions.state" - local builtin = require "telescope.builtin" - local themes = require "telescope.themes" - - local function narrow_picker(prompt_bufnr) - local picker = action_state.get_current_picker(prompt_bufnr) - local manager = picker.manager - local results = {} - - if #picker:get_multi_selection() > 0 then - for _, entry in ipairs(picker:get_multi_selection()) do - table.insert(results, entry) - print(vim.inspect(entry)) + local function buffers_instead(prompt_bufnr) + local picker = action_state.get_current_picker(prompt_bufnr) + local prompt_text = picker:_get_prompt() + builtin.buffers(themes.get_ivy({ default_text = prompt_text })) end - else - for entry in manager:iter() do - table.insert(results, entry) + + local function find_files_instead(prompt_bufnr) + local picker = action_state.get_current_picker(prompt_bufnr) + local prompt_text = picker:_get_prompt() + builtin.find_files(themes.get_ivy({ default_text = prompt_text })) end - end - local finder = finders.new_table { - results = results, - entry_maker = function(entry) return entry end, - } + -- UFO will not apply folds if we start from insert mode, + -- so stop insert and perform the same action in normal mode + local stop_insert_first = function(key) + return function(prompt_bufnr) + vim.cmd([[stopinsert]]) + vim.cmd(string.format('exe "normal %s"', key)) + end + end - picker:refresh(finder, { reset_prompt = true }) - end + local function table_keys_to_string(tbl, delimiter) + local keys = {} + for key, _ in pairs(tbl) do + table.insert(keys, key) + end + return table.concat(keys, delimiter) + end - local function buffers_instead(prompt_bufnr) - local picker = action_state.get_current_picker(prompt_bufnr) - local prompt_text = picker:_get_prompt() - builtin.buffers(themes.get_ivy({ default_text = prompt_text })) - end + local function cmp_tab(prompt_bufnr) + if cmp.visible() then + cmp.select_next_item({ behavior = cmp.SelectBehavior }) + else + actions.toggle_selection(prompt_bufnr) + actions.move_selection_worse(prompt_bufnr) + end + end - local function find_files_instead(prompt_bufnr) - local picker = action_state.get_current_picker(prompt_bufnr) - local prompt_text = picker:_get_prompt() - builtin.find_files(themes.get_ivy({ default_text = prompt_text })) - end + local function cmp_s_tab(prompt_bufnr) + if cmp.visible() then + cmp.select_previous_item({ behavior = cmp.SelectBehavior }) + else + actions.toggle_selection(prompt_bufnr) + actions.move_selection_better(prompt_bufnr) + end + end - -- UFO will not apply folds if we start from insert mode, - -- so stop insert and perform the same action in normal mode - local stop_insert_first = function(key) - return function(prompt_bufnr) - vim.cmd[[stopinsert]] - vim.cmd(string.format("exe \"normal %s\"", key)) - end - end + local function cmp_cr(prompt_bufnr) + if cmp.visible() then + cmp.confirm() + else + actions.select_default(prompt_bufnr) + end + end - require'telescope'.setup { - defaults = { - cache_pickers = { - num_pickers = 20, - limit_entries = 1000, - }, - mappings = { - i = { - [""] = "close", - [""] = actions.smart_add_to_qflist, - [""] = narrow_picker, - [""] = stop_insert_first("\\"), - [""] = stop_insert_first("\\"), - [""] = stop_insert_first("\\"), - [""] = false, - }, - n = { - [""] = "close", - [""] = actions.smart_add_to_qflist, - [""] = narrow_picker, - [""] = false, - }, - }, - }, - pickers = { - buffers = { + telescope.setup({ + defaults = { + cache_pickers = { + num_pickers = 20, + limit_entries = 1000, + }, mappings = { i = { - [""] = find_files_instead, + [""] = "close", + [""] = actions.smart_add_to_qflist, + [""] = narrow_picker, + [""] = stop_insert_first("\\"), + [""] = stop_insert_first("\\"), + [""] = stop_insert_first("\\"), + [""] = false, + [""] = cmp_tab, + [""] = cmp_s_tab, + [""] = cmp_cr, }, n = { - [""] = find_files_instead, + [""] = "close", + [""] = actions.smart_add_to_qflist, + [""] = narrow_picker, + [""] = false, + [""] = cmp_tab, + [""] = cmp_s_tab, + [""] = cmp_cr, }, }, }, - find_files = { - no_ignore = true, - mappings = { - i = { - [""] = buffers_instead, + pickers = { + buffers = { + mappings = { + i = { + [""] = find_files_instead, + }, + n = { + [""] = find_files_instead, + }, }, - n = { - [""] = buffers_instead, + }, + find_files = { + no_ignore = true, + mappings = { + i = { + [""] = buffers_instead, + }, + n = { + [""] = buffers_instead, + }, }, }, }, - }, - } - - vim.api.nvim_set_keymap('n', '[telescope]', '', { noremap = true }) - vim.api.nvim_set_keymap('n', '', '[telescope]', {}) - vim.keymap.set('n', '[telescope]/', function () builtin.buffers(themes.get_ivy()) end, { noremap = true }) - vim.keymap.set('n', '[telescope]f', function () builtin.live_grep(themes.get_ivy()) end, { noremap = true }) - vim.keymap.set('n', '[telescope]y', function () builtin.registers(themes.get_ivy()) end, { noremap = true }) - vim.keymap.set('n', '[telescope]q', function () builtin.quickfix(themes.get_ivy()) end, { noremap = true }) - vim.keymap.set('n', '[telescope].', function () builtin.resume(themes.get_ivy()) end, { noremap = true }) - end - } - ---}}} - - ---lsp config {{{ - -- neovim built-in language server - use { - 'neovim/nvim-lspconfig', - after = { - 'mason.nvim', - }, - requires = { - 'hrsh7th/nvim-cmp', - 'barreiroleo/ltex-extra.nvim' - }, - config = function () + }) + + vim.api.nvim_set_keymap("n", "[telescope]", "", { noremap = true }) + vim.api.nvim_set_keymap("n", "", "[telescope]", {}) + vim.keymap.set("n", "[telescope]/", function() + builtin.buffers(themes.get_ivy()) + end, { noremap = true }) + vim.keymap.set("n", "[telescope]f", function() + builtin.live_grep(themes.get_ivy()) + end, { noremap = true }) + vim.keymap.set("n", "[telescope]y", function() + builtin.registers(themes.get_ivy()) + end, { noremap = true }) + vim.keymap.set("n", "[telescope]q", function() + builtin.quickfix(themes.get_ivy()) + end, { noremap = true }) + vim.keymap.set("n", "[telescope].", function() + builtin.resume(themes.get_ivy()) + end, { noremap = true }) + end, + }) + ---}}} - ----config {{{ - vim.lsp.set_log_level("ERROR") + ---none-ls {{{ + use({ + "nvimtools/none-ls.nvim", + requires = { "nvim-lua/plenary.nvim" }, + }) + ---}}} + + ---lsp {{{ + -- neovim built-in language server + use({ + "neovim/nvim-lspconfig", + after = { + "mason.nvim", + }, + requires = { + "hrsh7th/nvim-cmp", + "barreiroleo/ltex-extra.nvim", + "nvimtools/none-ls.nvim", + }, + config = function() + ----config {{{ + vim.lsp.set_log_level("ERROR") - local lspconfig = require'lspconfig' + local lspconfig = require("lspconfig") - local capabilities = vim.lsp.protocol.make_client_capabilities() - capabilities = require'cmp_nvim_lsp'.default_capabilities(capabilities) - capabilities.textDocument.completion.completionItem.snippetSupport = true + local capabilities = vim.lsp.protocol.make_client_capabilities() + capabilities = require("cmp_nvim_lsp").default_capabilities(capabilities) + capabilities.textDocument.completion.completionItem.snippetSupport = true - local opts = { noremap = true, silent = true } + local opts = { noremap = true, silent = true } - vim.api.nvim_set_keymap('n', 'gS', 'lua vim.lsp.stop_client(vim.lsp.get_active_clients())', - { noremap = true}) + -- on_attach {{{ + local on_attach = function(client, bufnr) + -- local msg = "Attaching " .. client.name .. " LSP in buffer " .. bufnr .. "." + -- vim.api.nvim_echo({{msg, None}}, true, {}) - -- on_attach is only called after the language server - -- attaches to the buffer - local on_attach = function(client, bufnr) + -- diagnostic {{{ - print("Attaching ", client.name, " LSP in buffer ", bufnr, "...") + -- diagnostic without clutter + vim.diagnostic.config({ virtual_text = false, signs = false }) - -- diagnostic + telescope_diagnostic_picker = function() + local pickers = require("telescope_pickers") + local themes = require("telescope.themes") + local actions = require("telescope.actions") + local action_state = require("telescope.actions.state") - -- diagnostic without clutter - vim.diagnostic.config({ virtual_text = false, signs = false }) + local _diagnostic_picker = nil - telescope_diagnostic_picker = function() + local function toggle_diagnostic(prompt_bufnr) + local picker = action_state.get_current_picker(prompt_bufnr) + local prompt_text = picker:_get_prompt() + if picker.prompt_title == "Diagnostics - Buffer" then + new_prompt_title = "Diagnostics - Workspace" + new_key = "" + new_picker_bufnr = nil + else + new_prompt_title = "Diagnostics - Buffer" + new_key = "" + new_picker_bufnr = 0 + end + pcall(actions.close, prompt_bufnr) + _diagnostic_picker(new_prompt_title, prompt_text, new_picker_bufnr, new_key) + end - local builtin = require "telescope.builtin" - local themes = require "telescope.themes" - local actions = require "telescope.actions" - local action_state = require "telescope.actions.state" + _diagnostic_picker = function(prompt_title, default_text, bufnr, key) + pickers.diagnostics(themes.get_ivy({ + prompt_title = prompt_title, + default_text = default_text, + bufnr = bufnr, + attach_mappings = function(_, map) + map({ "i", "n" }, key, toggle_diagnostic) + return true + end, + })) + end - local _diagnostic_picker = nil + _diagnostic_picker("Diagnostics - Buffer", "", 0, "") + end - local function toggle_diagnostic(prompt_bufnr) - local picker = action_state.get_current_picker(prompt_bufnr) - local prompt_text = picker:_get_prompt() - if picker.prompt_title == "Diagnostics - Buffer" then - new_prompt_title = "Diagnostics - Workspace" - new_key = "" - new_picker_bufnr = nil + vim.keymap.set("n", "[telescope]l", function() + telescope_diagnostic_picker(nil) + end) + + local diagnostic_hidden = {} + + function diagnostic_toggle(toggle_bufnr, revert) + toggle_bufnr = vim.api.nvim_buf_get_number(toggle_bufnr) + print("Toggle diagnostics", toggle_bufnr, diagnostic_hidden[toggle_bufnr]) + if + (diagnostic_hidden[toggle_bufnr] and not revert) + or (not diagnostic_hidden[toggle_bufnr] and revert) + then + vim.diagnostic.enable(toggle_bufnr, nil) + diagnostic_hidden[toggle_bufnr] = false else - new_prompt_title = "Diagnostics - Buffer" - new_key = "" - new_picker_bufnr = 0 + vim.diagnostic.disable(toggle_bufnr, nil) + diagnostic_hidden[toggle_bufnr] = true end - pcall(actions.close, prompt_bufnr) - _diagnostic_picker(new_prompt_title, prompt_text, new_picker_bufnr, new_key) end - _diagnostic_picker = function(prompt_title, default_text, bufnr, key) - builtin.diagnostics(themes.get_ivy({ - prompt_title = prompt_title, - default_text = default_text, - bufnr = bufnr, - attach_mappings = function(_, map) - map({"i", "n"}, key, toggle_diagnostic) - return true - end, - })) - end + vim.api.nvim_buf_set_keymap(bufnr, "n", "gl", "lua diagnostic_toggle(0)", opts) + vim.api.nvim_buf_set_keymap(bufnr, "n", "gL", "lua vim.diagnostic.open_float()", opts) + vim.api.nvim_buf_set_keymap(bufnr, "n", "]d", "lua vim.diagnostic.goto_next()", opts) + vim.api.nvim_buf_set_keymap(bufnr, "n", "[d", "lua vim.diagnostic.goto_prev()", opts) - _diagnostic_picker("Diagnostics - Buffer", ":error:", 0, "") + -- }}} - end + -- formatting {{{ - vim.keymap.set('n', '[telescope]l', function() telescope_diagnostic_picker(nil) end) + local function is_null_ls_formatting_enabled(bufnr) + local file_type = vim.api.nvim_buf_get_option(bufnr, "filetype") + local generators = + require("null-ls.generators").get_available(file_type, require("null-ls.methods").internal.FORMATTING) + return #generators > 0 + end - local diagnostic_hidden = {} + -- see https://github.com/astral-sh/ruff/issues/11634 + -- see https://github.com/nvimtools/none-ls.nvim/wiki/Avoiding-LSP-formatting-conflicts + vim.bo[bufnr].formatexpr = nil - function diagnostic_toggle(toggle_bufnr, revert) - toggle_bufnr = vim.api.nvim_buf_get_number(toggle_bufnr) print("Toggle diagnostics", toggle_bufnr, diagnostic_hidden[toggle_bufnr]) - if (diagnostic_hidden[toggle_bufnr] and not revert) or - (not diagnostic_hidden[toggle_bufnr] and revert) then - vim.diagnostic.enable(toggle_bufnr, nil) - diagnostic_hidden[toggle_bufnr] = false - else - vim.diagnostic.disable(toggle_bufnr, nil) - diagnostic_hidden[toggle_bufnr] = true + if client.server_capabilities.documentFormattingProvider then + if client.name == "null-ls" and is_null_ls_formatting_enabled(bufnr) or client.name ~= "null-ls" then + -- vim.bo[bufnr].formatexpr = "v:lua.vim.lsp.formatexpr()" + vim.keymap.set({ "n", "v" }, "gq", function() + vim.lsp.buf.format({ async = true }) + end, opts) + end end - end - vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gl', - 'lua diagnostic_toggle(0)', opts) - vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gL', - 'lua vim.diagnostic.open_float()', opts) - vim.api.nvim_buf_set_keymap(bufnr, 'n', ']d', - 'lua vim.diagnostic.goto_next()', opts) - vim.api.nvim_buf_set_keymap(bufnr, 'n', '[d', - 'lua vim.diagnostic.goto_prev()', opts) - - -- documentation help - vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gD', - 'lua vim.lsp.buf.declaration()', opts) - vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gd', - 'lua vim.lsp.buf.definition()', opts) - vim.api.nvim_buf_set_keymap(bufnr, 'n', 'K', - 'lua vim.lsp.buf.signature_help()', opts) - - -- code action - vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gA', - 'lua vim.lsp.buf.code_action()', opts) - - -- variable management - vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gr', - 'lua vim.lsp.buf.rename()', opts) - - -- formatting - vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gQ', - 'lua vim.lsp.buf.formatting()', opts) - - -- language specific - if (client.name == 'texlab') then - vim.api.nvim_buf_set_keymap(bufnr, 'n', '', - 'echo \'Building file.\'TexlabBuild', opts) - vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gt', - 'TexlabForward', opts) - end + -- }}} - if (client.name == "ltex") then - -- tmpdir = vim.api.nvim_eval[[tempname()]] .. "-ltex" - require'ltex_extra'.setup { - load_langs = { 'en-US' }, - init_check = true, - path = '.ltex', -- tmpdir - } - end - end + -- documentation help {{{ + vim.api.nvim_buf_set_keymap(bufnr, "n", "gD", "lua vim.lsp.buf.declaration()", opts) + vim.api.nvim_buf_set_keymap(bufnr, "n", "gd", "lua vim.lsp.buf.definition()", opts) + vim.api.nvim_buf_set_keymap(bufnr, "n", "K", "lua vim.lsp.buf.signature_help()", opts) - local function my_config(config) - config = config or {} - local defaults = { - on_attach = on_attach, - autostart = false, - capabilities = capabilities, - } - return vim.tbl_deep_extend("keep", config, defaults) - end - ----}}} + -- code action + vim.api.nvim_buf_set_keymap(bufnr, "n", "gA", "lua vim.lsp.buf.code_action()", opts) - ----servers {{{ - -- https://github.com/neovim/nvim-lspconfig/blob/master/CONFIG.md - -- to check status: :lua vim.cmd('split'..vim.lsp.get_log_path()) - -- to check start options: :help lsp.start + -- variable management + vim.api.nvim_buf_set_keymap(bufnr, "n", "gr", "lua vim.lsp.buf.rename()", opts) - -----vim {{{ - lspconfig.vimls.setup(my_config()) - -----}}} + -- }}} - -----html {{{ - lspconfig.html.setup(my_config()) - -----}}} + -- server specific {{{ + if client.name == "texlab" then + vim.api.nvim_buf_set_keymap( + bufnr, + "n", + "", + "echo 'Building file.'TexlabBuild", + opts + ) + vim.api.nvim_buf_set_keymap(bufnr, "n", "gt", "TexlabForward", opts) + end - -----julia {{{ - lspconfig.julials.setup(my_config()) - -----}}} + if client.name == "ltex" then + -- tmpdir = vim.api.nvim_eval[[tempname()]] .. "-ltex" + require("ltex_extra").setup({ + load_langs = { "en-US" }, + init_check = true, + path = ".ltex", -- tmpdir + }) + end - -----python {{{ - lspconfig.pyright.setup( - my_config({ - settings = { - python = { - venvPath = vim.env.HOME .. '/.pyenv/versions' - } + -- }}} + end + -- }}} + + -- my_config {{{ + local function my_config(config) + config = config or {} + local defaults = { + on_attach = on_attach, + autostart = false, + capabilities = capabilities, } - }) - ) - -----}}} - - -----json {{{ - lspconfig.jsonls.setup(my_config()) - -----}}} - - -----text {{{ - lspconfig.ltex.setup( - my_config({ - settings = { - ltex = { - disabledRules = { - -- ["en"] = { "PROFANITY" }, -- "MORFOLOGIK_RULE_EN" - -- ["en-GB"] = { "PROFANITY" }, -- "MORFOLOGIK_RULE_EN_GB" - ["en-US"] = { "PROFANITY" }, -- "MORFOLOGIK_RULE_EN_US", + return vim.tbl_deep_extend("keep", config, defaults) + end + -- }}} + ----}}} + + ----servers {{{ + -- https://github.com/neovim/nvim-lspconfig/blob/master/CONFIG.md + -- to check status: :lua vim.cmd('split'..vim.lsp.get_log_path()) + -- to check start options: :help lsp.start + + ----null-ls {{{ + local null_ls = require("null-ls") + null_ls.setup({ + debug = false, + fallback_severity = vim.diagnostic.severity.WARN, + sources = { + null_ls.builtins.diagnostics.codespell, + null_ls.builtins.formatting.stylua, + null_ls.builtins.diagnostics.mypy.with({ + condition = function() + return vim.fn.executable("mypy") == 1 and vim.system({ "mypy", "--version" }):wait().code == 0 + end, + -- see issue https://github.com/nvimtools/none-ls.nvim/issues/97 + args = function(params) + -- local pyenv_version = vim.system({ "pyenv", "version-name" }):wait() + -- local pyenv_exists = pyenv_version.code == 0 + -- local pyenv_version = pyenv_version.stdout:gsub("%s+", "") + -- local python_path + -- if pyenv_exists and pyenv_version ~= "system" then + -- python_path = vim.system({ "pyenv", "which", "python" }):wait().stdout:gsub("%s+", "") + -- else + -- local mason_mypy_python = vim.fn.stdpath("data") .. "/mason/packages/mypy/venv/bin/python" + -- if vim.fn.filereadable(mason_mypy_python) == 1 and vim.fn.executable(mason_mypy_python) then + -- python_path = mason_mypy_python + -- else + -- if pyenv_exists then + -- python_path = vim.system({ "pyenv", "which", "python3" }):wait().stdout:gsub("%s+", "") + -- else + -- python_path = vim.system({ "which", "python" }):wait().stdout + -- end + -- end + -- end + -- vim.api.nvim_echo({{python_path}}, true, {}) + -- vim.system({ + -- "mypy", + -- "--install-types", + -- "--non-interactive", + -- "--python-executable", + -- python_path, + -- }):wait() + return { + "--hide-error-codes", + "--hide-error-context", + "--no-color-output", + "--show-absolute-path", + "--show-column-numbers", + "--show-error-codes", + "--no-error-summary", + "--ignore-missing-imports", + "--no-pretty", + -- "--python-executable", + -- python_path, + params.temp_path, + } + end, + on_output = function(line, params) + line = line:gsub(params.temp_path:gsub("([^%w])", "%%%1"), params.bufname) + return null_ls.builtins.diagnostics.mypy._opts.on_output(line, params) + end, + }), + }, + on_attach = on_attach, + }) + ----}}} + + -----vim {{{ + lspconfig.vimls.setup(my_config()) + -----}}} + + -----html {{{ + lspconfig.html.setup(my_config()) + -----}}} + + -----julia {{{ + lspconfig.julials.setup(my_config()) + -----}}} + + -----python {{{ + -- see https://github.com/astral-sh/ruff/blob/main/crates/ruff_server/docs/setup/NEOVIM.md + lspconfig.ruff.setup(my_config({ autostart = true })) + lspconfig.pyright.setup( + my_config({ + autostart = true, + settings = { + pyright = { + -- using Ruff's import organizer + disableOrganizeImports = true, + }, + python = { + venvPath = vim.env.HOME .. '/.pyenv/versions', + analysis = { + -- ignore all files for analysis to exclusively use Ruff for linting + ignore = { '*'}, + }, + } + } + }) + ) + -----}}} + + -----json {{{ + lspconfig.jsonls.setup(my_config()) + -----}}} + + -----text {{{ + lspconfig.ltex.setup(my_config({ + settings = { + ltex = { + disabledRules = { + -- ["en"] = { "PROFANITY" }, -- "MORFOLOGIK_RULE_EN" + -- ["en-GB"] = { "PROFANITY" }, -- "MORFOLOGIK_RULE_EN_GB" + ["en-US"] = { "PROFANITY" }, -- "MORFOLOGIK_RULE_EN_US", + }, }, }, - }, - filetypes = { 'bib', 'gitcommit', 'markdown', 'org', 'plaintex', 'rst', 'rnoweb', 'tex', 'pandoc', 'quarto', 'rmd', 'typst' }, - get_language_id = function(bufnr, filetype) + filetypes = { + "bib", + "gitcommit", + "markdown", + "org", + "plaintex", + "rst", + "rnoweb", + "tex", + "pandoc", + "quarto", + "rmd", + "typst", + }, + get_language_id = function(bufnr, filetype) buf_name = vim.api.nvim_buf_get_name(bufnr) if buf_name:match(".sty$") then -- set the language-id, to one for which ltex parsing is disabled @@ -372,375 +562,349 @@ require'packer'.startup {function (use) else -- from nvim-lspconfig/lua/lua/lspconfig/server_configurations/ltex.lua language_id_mapping = { - bib = 'bibtex', - plaintex = 'tex', - rnoweb = 'sweave', - rst = 'restructuredtext', - tex = 'latex', - xhtml = 'xhtml', - typst = 'text', + bib = "bibtex", + plaintex = "tex", + rnoweb = "sweave", + rst = "restructuredtext", + tex = "latex", + xhtml = "xhtml", + typst = "text", } - local language_id = language_id_mapping[filetype] + local language_id = language_id_mapping[filetype] if language_id then return language_id else return filetype end end - end - }) - ) - -----}}} - - -----latex {{{ - -- https://github.com/wbthomason/dotfiles/blob/linux/neovim/.config/nvim/plugin/lsp.lua#L168 - lspconfig.texlab.setup( - my_config({ - settings = { - texlab = { - build = { args = { "-lualatex", "-interaction=nonstopmode", "--shell-escape", "-synctex=1", "%f" } }, - chktex = { onOpenAndSave = true, }, - formatterLineLengh = 0, - forwardSearch = { executable = 'zathura', args = { '--synctex-forward=%l:1:%f', '%p' } }, + end, + })) + -----}}} + + -----latex {{{ + -- https://github.com/wbthomason/dotfiles/blob/linux/neovim/.config/nvim/plugin/lsp.lua#L168 + lspconfig.texlab.setup(my_config({ + settings = { + texlab = { + build = { args = { "-lualatex", "-interaction=nonstopmode", "--shell-escape", "-synctex=1", "%f" } }, + chktex = { onOpenAndSave = true }, + formatterLineLengh = 0, + forwardSearch = { executable = "zathura", args = { "--synctex-forward=%l:1:%f", "%p" } }, + }, }, - }, - }) - ) - -----}}} - - -----clang {{{ - lspconfig.clangd.setup(my_config()) - -----}}} - - -----bash {{{ - lspconfig.bashls.setup(my_config()) - -----}}} - - -----lua {{{ - lspconfig.lua_ls.setup( - my_config({ - settings = { - Lua = { - diagnostics = { - globals = { "vim" }, - disable = { "lowercase-global" }, - runtime = { version = "LuaJIT", path = vim.split(package.path, ';') }, - workspace = { - library = { - [vim.fn.expand "$VIMRUNTIME/lua"] = true, - [vim.fn.expand "$VIMRUNTIME/lua/vim/lsp"] = true, + })) + -----}}} + + -----clang {{{ + lspconfig.clangd.setup(my_config()) + -----}}} + + -----bash {{{ + lspconfig.bashls.setup(my_config()) + -----}}} + + -----lua {{{ + lspconfig.lua_ls.setup(my_config({ + autostart = true, + settings = { + Lua = { + diagnostics = { + globals = { "vim" }, + disable = { "lowercase-global" }, + runtime = { version = "LuaJIT", path = vim.split(package.path, ";") }, + workspace = { + library = { + [vim.fn.expand("$VIMRUNTIME/lua")] = true, + [vim.fn.expand("$VIMRUNTIME/lua/vim/lsp")] = true, + }, }, }, }, }, - }, - }) - ) - -----}}} - - -----ruby {{{ - lspconfig.solargraph.setup( - my_config({ - settings = { - solargraph = { - diagnostic = true, - useBundler = true + })) + -----}}} + + -----ruby {{{ + lspconfig.solargraph.setup(my_config({ + settings = { + solargraph = { + diagnostic = true, + useBundler = true, + }, }, - }, - }) - ) - -----}}} - - -----css {{{ - lspconfig.stylelint_lsp.setup( - my_config({ - settings = { + })) + -----}}} + + -----css {{{ + lspconfig.stylelint_lsp.setup(my_config({ + settings = { stylelintplus = { autoFixOnSave = true, - autoFixOnFormat = true + autoFixOnFormat = true, + }, }, - }, - }) - ) - -----}}} - - -----racket {{{ - lspconfig.racket_langserver.setup(my_config()) - -----}}} - - -----beancount {{{ - lspconfig.beancount.setup(my_config()) - -----}}} - - -----typst {{{ - lspconfig.typst_lsp.setup( - my_config({ - settings = { - exportPdf = "never", - }, - }) - ) - -----}}} - - -----hoon {{{ - lspconfig.hoon_ls.setup( - my_config({ - cmd = {"hoon-language-server", "-p", "8080"}, - }) - ) - -----}}} - - ----}}} - - end, - } - ---}}} + })) + -----}}} - ---treesiter {{{ - -- an incremental parsing system for programming tools - use { - 'nvim-treesitter/nvim-treesitter', - -- run = ':TSUpdate', - config = function () - -- https://github.com/nvim-treesitter/nvim-treesitter#adding-parsers - local parser_config = require "nvim-treesitter.parsers".get_parser_configs() - parser_config.typst = { - install_info = { - url = "https://github.com/uben0/tree-sitter-typst", -- local path or git repo - files = {"src/parser.c", "src/scanner.c"}, -- note that some parsers also require src/scanner.c or src/scanner.cc - -- optional entries: - branch = "master", -- default branch in case of git repo if different from master - generate_requires_npm = false, -- if stand-alone parser without npm dependencies - requires_generate_from_grammar = false, -- if folder contains pre-generated src/parser.c - }, - } - require'nvim-treesitter.install'.update() - require'nvim-treesitter.configs'.setup { - ensure_installed = 'all', -- one of 'all', 'maintained', or a list of languages - ignore_install = { }, -- List of parsers to ignore installing - highlight = { - enable = true, - -- Setting this to true will run `:h syntax` and tree-sitter at the same time. - -- Set to `true` if you depend on 'syntax' being enabled. - -- This option may slow down the editor, and cause duplicate highlights. - -- Instead of true it can also be a list of languages - -- additional_vim_regex_highlighting = { 'org' }, - additional_vim_regex_highlighting = false, - }, - incremental_selection = { - enable = true, - keymaps = { - init_selection = 'gnn', - node_incremental = 'n', - scope_incremental = 'gs', - node_decremental = 'N', + -----typst {{{ + lspconfig.typst_lsp.setup(my_config({ + settings = { + exportPdf = "never", }, - }, - indent = { - enable = true, - disable = { "julia" } - }, - query_linter = { - enable = true, - use_virtual_text = true, - lint_events = {"BufWrite", "CursorHold"}, - }, - } - end - } - -- debugging and learning about treesitter - use { - 'nvim-treesitter/playground', - requires = { 'nvim-treesitter/nvim-treesitter', opt = true } - } - ---}}} + })) + -----}}} - ---lualine/tmuxline {{{ - -- lean & mean status for vim that's light as air - use { - 'nvim-lualine/lualine.nvim', - requires = { 'stevearc/aerial.nvim' }, - config = function () - require'lualine'.setup({ - sections = { - lualine_b = { - 'branch', - 'filename', - }, - lualine_c = { - { - 'aerial', - sep = '  ', - colored = false, + ----}}} + end, + }) + ---}}} + + ---treesiter {{{ + -- an incremental parsing system for programming tools + use({ + "nvim-treesitter/nvim-treesitter", + -- run = ':TSUpdate', + config = function() + -- https://github.com/nvim-treesitter/nvim-treesitter#adding-parsers + local parser_config = require("nvim-treesitter.parsers").get_parser_configs() + parser_config.typst = { + install_info = { + url = "https://github.com/uben0/tree-sitter-typst", -- local path or git repo + files = { "src/parser.c", "src/scanner.c" }, -- note that some parsers also require src/scanner.c or src/scanner.cc + -- optional entries: + branch = "master", -- default branch in case of git repo if different from master + generate_requires_npm = false, -- if stand-alone parser without npm dependencies + requires_generate_from_grammar = false, -- if folder contains pre-generated src/parser.c + }, + } + require("nvim-treesitter.install").update() + require("nvim-treesitter.configs").setup({ + ensure_installed = "all", -- one of 'all', 'maintained', or a list of languages + sync_install = false, + auto_install = false, + ignore_install = {}, -- List of parsers to ignore installing + highlight = { + enable = true, + -- Setting this to true will run `:h syntax` and tree-sitter at the same time. + -- Set to `true` if you depend on 'syntax' being enabled. + -- This option may slow down the editor, and cause duplicate highlights. + -- Instead of true it can also be a list of languages + -- additional_vim_regex_highlighting = { 'org' }, + additional_vim_regex_highlighting = false, }, - }, - lualine_x = { - { - 'diagnostics', - symbols = { error = 'E', warn = 'W', info = 'I', hint = 'H'}, + incremental_selection = { + enable = true, + keymaps = { + init_selection = "gnn", + node_incremental = "n", + scope_incremental = "gs", + node_decremental = "N", + }, }, - 'diff', - }, - lualine_y = { 'progress' }, - lualine_z = { - 'location', - 'filetype', - }, - } + indent = { + enable = true, + disable = { "julia" }, + }, + query_linter = { + enable = true, + use_virtual_text = true, + lint_events = { "BufWrite", "CursorHold" }, + }, + }) + end, }) - end - } - ---}}} - - ---vim-oscyank {{{ - -- copy text through SSH with OSC52 - use { - 'ojroques/vim-oscyank', - config = function() - vim.cmd [[ + -- debugging and learning about treesitter + use({ + "nvim-treesitter/playground", + requires = { "nvim-treesitter/nvim-treesitter", opt = true }, + }) + ---}}} + + ---lualine/tmuxline {{{ + -- lean & mean status for vim that's light as air + use({ + "nvim-lualine/lualine.nvim", + requires = { "stevearc/aerial.nvim" }, + config = function() + require("lualine").setup({ + sections = { + lualine_b = { + "branch", + "filename", + }, + lualine_c = { + { + "aerial", + sep = "  ", + colored = false, + }, + }, + lualine_x = { + { + "diagnostics", + symbols = { error = "E", warn = "W", info = "I", hint = "H" }, + }, + "diff", + }, + lualine_y = { "progress" }, + lualine_z = { + "location", + "filetype", + }, + }, + }) + end, + }) + ---}}} + + ---vim-oscyank {{{ + -- copy text through SSH with OSC52 + use({ + "ojroques/vim-oscyank", + config = function() + vim.cmd([[ augroup oscyank autocmd TextYankPost * if v:event.operator is 'y' && v:event.regname is '+' | execute 'OSCYankRegister +' | endif augroup end - ]] - end - } - ---}}} - - ---neoscroll {{{ - -- smooth scrolling - use { - 'karb94/neoscroll.nvim', - config = function() - require'neoscroll'.setup({ - mappings = {}, - }) - end, - } - ---}}} - - ---nnn {{{ - use { - 'gzagatti/nnn.nvim', - branch = 'tweaks', - config = function() - local builtin = require'nnn'.builtin - require'nnn'.setup { - explorer = { - cmd = "nnn", - }, - picker = { - cmd = "tmux new-session nnn -Pp", - }, - auto_open = { - empty = true, - }, - mappings = { - {"", function (files) - local nnnwin - for _, win in pairs(vim.api.nvim_tabpage_list_wins(0)) do - if vim.api.nvim_buf_get_option(vim.api.nvim_win_get_buf(win), "filetype") == "nnn" then - nnnwin = win - break - end - end - for i, file in ipairs(files) do - if i == 1 and vim.api.nvim_buf_get_name(0) == "" then - vim.cmd("edit "..file) - else - vim.cmd("split "..file) - end - end - vim.api.nvim_set_current_win(nnnwin) - end - }, - {"", function (files) - local nnnwin - for _, win in pairs(vim.api.nvim_tabpage_list_wins(0)) do - if vim.api.nvim_buf_get_option(vim.api.nvim_win_get_buf(win), "filetype") == "nnn" then - nnnwin = win - break - end - end - for i, file in ipairs(files) do - if i == 1 and vim.api.nvim_buf_get_name(0) == "" then - vim.cmd("edit "..file) - else - vim.cmd("vsplit "..file) - end - end - vim.api.nvim_set_current_win(nnnwin) - end - }, - }, - quitcd = "cd", - } - vim.api.nvim_set_keymap( - "", - "", - ":execute 'NnnExplorer' (expand('%:p') ==? expand('%:.') ? '%:p:h' : '')", - { noremap = true, silent = true } - ) - vim.cmd [[ + ]]) + end, + }) + ---}}} + + ---neoscroll {{{ + -- smooth scrolling + use({ + "karb94/neoscroll.nvim", + config = function() + require("neoscroll").setup({ + mappings = {}, + }) + end, + }) + ---}}} + + ---nnn {{{ + if vim.fn.executable("nnn") then + use({ + "gzagatti/nnn.nvim", + branch = "tweaks", + config = function() + local builtin = require("nnn").builtin + require("nnn").setup({ + explorer = { + cmd = "nnn", + }, + picker = { + cmd = "tmux new-session nnn -Pp", + }, + auto_open = { + empty = true, + }, + mappings = { + { + "", + function(files) + local nnnwin + for _, win in pairs(vim.api.nvim_tabpage_list_wins(0)) do + if vim.api.nvim_buf_get_option(vim.api.nvim_win_get_buf(win), "filetype") == "nnn" then + nnnwin = win + break + end + end + for i, file in ipairs(files) do + if i == 1 and vim.api.nvim_buf_get_name(0) == "" then + vim.cmd("edit " .. file) + else + vim.cmd("split " .. file) + end + end + vim.api.nvim_set_current_win(nnnwin) + end, + }, + { + "", + function(files) + local nnnwin + for _, win in pairs(vim.api.nvim_tabpage_list_wins(0)) do + if vim.api.nvim_buf_get_option(vim.api.nvim_win_get_buf(win), "filetype") == "nnn" then + nnnwin = win + break + end + end + for i, file in ipairs(files) do + if i == 1 and vim.api.nvim_buf_get_name(0) == "" then + vim.cmd("edit " .. file) + else + vim.cmd("vsplit " .. file) + end + end + vim.api.nvim_set_current_win(nnnwin) + end, + }, + }, + quitcd = "cd", + }) + vim.api.nvim_set_keymap( + "", + "", + ":execute 'NnnExplorer' (expand('%:p') ==? expand('%:.') ? '%:p:h' : '')", + { noremap = true, silent = true } + ) + vim.cmd([[ augroup nnn autocmd FileType * if &ft ==# "nnn" |:tnoremap q| endif augroup end - ]] - end - } - ---}}} - - ---kommentary {{{ - -- easily add comments in source code - use { - 'b3nj5m1n/kommentary', - config = function() - vim.g.kommentary_create_default_mappings = false - require'kommentary.config'.configure_language("default", { prefer_single_line_comments = true, }) - vim.api.nvim_set_keymap("n", "cc", "kommentary_line_default", {}) - vim.api.nvim_set_keymap("n", "c", "kommentary_motion_default", {}) - vim.api.nvim_set_keymap("x", "c", "kommentary_visual_default", {}) - end - } - ---}}} - - ---navigators {{{ - -- kitty-navigator - use { - 'knubie/vim-kitty-navigator', - config = function() - if vim.env.TERM ~= 'xterm-kitty' then - vim.g['kitty_navigator_no_mappings'] = 1 - end - end, - } - - -- tmux-navigator - -- seamless navigation between tmux panes and vim splits - use { - 'christoomey/vim-tmux-navigator', - config = function() - if not string.match(vim.env.TERM, "tmux-") then - vim.g['tmux_navigator_no_mappings'] = 1 - vim.g ['tmux_navigator_disable_when_zoomed'] = 1 - end - end - } - ---}}} - - ---slime {{{ - -- multiplexer integration - use { - 'jpalardy/vim-slime', - config = function() - if vim.env.TERM == 'xterm-kitty' then - vim.g.slime_target = "kitty" - vim.g.slime_bracketed_paste = 1 - else - vim.g.slime_target = "tmux" - vim.g.slime_bracketed_paste = 1 + ]]) + end, + }) end + ---}}} + + ---kommentary {{{ + -- easily add comments in source code + use({ + "b3nj5m1n/kommentary", + config = function() + vim.g.kommentary_create_default_mappings = false + require("kommentary.config").configure_language("default", { prefer_single_line_comments = true }) + vim.api.nvim_set_keymap("n", "cc", "kommentary_line_default", {}) + vim.api.nvim_set_keymap("n", "c", "kommentary_motion_default", {}) + vim.api.nvim_set_keymap("x", "c", "kommentary_visual_default", {}) + end, + }) + ---}}} + + ---navigators {{{ + -- tmux-navigator + -- seamless navigation between tmux panes and vim splits + use({ + "christoomey/vim-tmux-navigator", + config = function() + if not string.match(vim.env.TERM, "tmux-") then + vim.g["tmux_navigator_no_mappings"] = 1 + vim.g["tmux_navigator_disable_when_zoomed"] = 1 + end + end, + }) + ---}}} + + ---slime {{{ + -- multiplexer integration + use({ + "jpalardy/vim-slime", + config = function() + if vim.env.TERM == "xterm-kitty" then + vim.g.slime_target = "kitty" + vim.g.slime_bracketed_paste = 1 + elseif vim.env.TERM == "wezterm" then + vim.g.slime_target = "wezterm" + vim.g.slime_bracketed_paste = 1 + else + vim.g.slime_target = "tmux" + vim.g.slime_bracketed_paste = 1 + end - vim.cmd[[ + vim.cmd([[ function! SlimeConfirm() abort if exists("b:slime_bracketed_paste") if b:slime_bracketed_paste @@ -764,17 +928,27 @@ require'packer'.startup {function (use) unlet b:slime_bracketed_paste endif endfunction - ]] - - vim.g.slime_no_mappings = 1 - - vim.api.nvim_set_keymap('', '[slime]', '', { noremap = true }) - vim.api.nvim_set_keymap('', 's', '[slime]', {}) - vim.api.nvim_set_keymap('' , '[slime]l', ':call slime#send_lines(v:count1) | call SlimeConfirm()', {}) - vim.api.nvim_set_keymap('v', '[slime]l', ':call slime#send_op(visualmode(), 1) | call SlimeConfirm()', {}) - vim.api.nvim_set_keymap('', '[slime]v', ':call slime#config()', {}) - vim.api.nvim_set_keymap('' , '[slime]b', ':call slime#send_range(line(1), line("$")) | call SlimeConfirm()', {}) - vim.cmd [[ + ]]) + + vim.g.slime_no_mappings = 1 + + vim.api.nvim_set_keymap("", "[slime]", "", { noremap = true }) + vim.api.nvim_set_keymap("", "s", "[slime]", {}) + vim.api.nvim_set_keymap("", "[slime]l", ":call slime#send_lines(v:count1) | call SlimeConfirm()", {}) + vim.api.nvim_set_keymap( + "v", + "[slime]l", + ":call slime#send_op(visualmode(), 1) | call SlimeConfirm()", + {} + ) + vim.api.nvim_set_keymap("", "[slime]v", ":call slime#config()", {}) + vim.api.nvim_set_keymap( + "", + "[slime]b", + ':call slime#send_range(line(1), line("$")) | call SlimeConfirm()', + {} + ) + vim.cmd([[ augroup slime_augroup: autocmd! @@ -812,156 +986,157 @@ require'packer'.startup {function (use) autocmd FileType org let b:slime_cell_delimiter = "#+" augroup END - ]] - end - } - ---}}} - - ---ufo {{{ - -- ultra fold - use { - 'kevinhwang91/nvim-ufo', - requires = { 'kevinhwang91/promise-async', 'nvim-treesitter/nvim-treesitter' }, - config = function() - require'ufo'.setup({ - open_fold_hl_timeout = 150, - provider_selector = function(bufnr, filetype, buftype) - return {'treesitter', 'indent'} + ]]) end, - enable_get_fold_virt_text = true, - fold_virt_text_handler = function(virtText, lnum, endLnum, width, truncate, ctx) - -- include the bottom line in folded text for additional context - local filling = ' ⋯ ' - local sufWidth = vim.fn.strdisplaywidth(suffix) - local targetWidth = width - sufWidth - local curWidth = 0 - table.insert(virtText, {filling, 'Folded'}) - -- do not add virtual text to title sections - local captures = vim.treesitter.get_captures_at_pos(ctx.bufnr, lnum-1, 0) - for _, c in pairs(captures) do - if c.capture:match("^org.headline") then - return virtText + }) + ---}}} + + ---ufo {{{ + -- ultra fold + use({ + "kevinhwang91/nvim-ufo", + requires = { "kevinhwang91/promise-async", "nvim-treesitter/nvim-treesitter" }, + config = function() + require("ufo").setup({ + open_fold_hl_timeout = 150, + provider_selector = function(bufnr, filetype, buftype) + return { "treesitter", "indent" } + end, + enable_get_fold_virt_text = true, + fold_virt_text_handler = function(virtText, lnum, endLnum, width, truncate, ctx) + -- include the bottom line in folded text for additional context + local filling = " ⋯ " + local sufWidth = vim.fn.strdisplaywidth(suffix) + local targetWidth = width - sufWidth + local curWidth = 0 + table.insert(virtText, { filling, "Folded" }) + -- do not add virtual text to title sections + local captures = vim.treesitter.get_captures_at_pos(ctx.bufnr, lnum - 1, 0) + for _, c in pairs(captures) do + if c.capture:match("^text.title") then + return virtText + end end - end - local endVirtText = ctx.get_fold_virt_text(endLnum) - for i, chunk in ipairs(endVirtText) do - local chunkText = chunk[1] - local hlGroup = chunk[2] - if i == 1 then - chunkText = chunkText:gsub("^%s+", "") - end - local chunkWidth = vim.fn.strdisplaywidth(chunkText) - if targetWidth > curWidth + chunkWidth then - table.insert(virtText, {chunkText, hlGroup}) - else - chunkText = truncate(chunkText, targetWidth - curWidth) - table.insert(virtText, {chunkText, hlGroup}) - chunkWidth = vim.fn.strdisplaywidth(chunkText) - -- str width returned from truncate() may less than 2nd argument, need padding - if curWidth + chunkWidth < targetWidth then - suffix = suffix .. (' '):rep(targetWidth - curWidth - chunkWidth) + local endVirtText = ctx.get_fold_virt_text(endLnum) + for i, chunk in ipairs(endVirtText) do + local chunkText = chunk[1] + local hlGroup = chunk[2] + if i == 1 then + chunkText = chunkText:gsub("^%s+", "") + end + local chunkWidth = vim.fn.strdisplaywidth(chunkText) + if targetWidth > curWidth + chunkWidth then + table.insert(virtText, { chunkText, hlGroup }) + else + chunkText = truncate(chunkText, targetWidth - curWidth) + table.insert(virtText, { chunkText, hlGroup }) + chunkWidth = vim.fn.strdisplaywidth(chunkText) + -- str width returned from truncate() may less than 2nd argument, need padding + if curWidth + chunkWidth < targetWidth then + suffix = suffix .. (" "):rep(targetWidth - curWidth - chunkWidth) + end + break + end + curWidth = curWidth + chunkWidth end - break - end - curWidth = curWidth + chunkWidth - end - return virtText + return virtText + end, + }) + vim.keymap.set("n", "zR", require("ufo").openAllFolds) + vim.keymap.set("n", "zM", require("ufo").closeAllFolds) + vim.keymap.set("n", "zr", require("ufo").openFoldsExceptKinds) + vim.keymap.set("n", "zm", require("ufo").closeFoldsWith) -- closeAllFolds == closeFoldsWith(0) + vim.api.nvim_create_autocmd("BufRead", { + callback = function() + vim.cmd([[ silent! foldclose! ]]) + local bufnr = vim.api.nvim_get_current_buf() + -- make sure buffer is attached + vim.wait(100, function() + require("ufo").attach(bufnr) + end) + if require("ufo").hasAttached(bufnr) then + local winid = vim.api.nvim_get_current_win() + local method = vim.wo[winid].foldmethod + if method == "diff" or method == "marker" then + require("ufo").closeAllFolds() + return + end + -- getFolds returns a Promise if providerName == 'lsp', use vim.wait in this case + local ok, ranges = pcall(require("ufo").getFolds, bufnr, "treesitter") + if ok and ranges then + if require("ufo").applyFolds(bufnr, ranges) then + pcall(require("ufo").closeAllFolds) + end + end + end + end, + }) end, }) - vim.keymap.set('n', 'zR', require'ufo'.openAllFolds) - vim.keymap.set('n', 'zM', require'ufo'.closeAllFolds) - vim.keymap.set('n', 'zr', require'ufo'.openFoldsExceptKinds) - vim.keymap.set('n', 'zm', require'ufo'.closeFoldsWith) -- closeAllFolds == closeFoldsWith(0) - vim.api.nvim_create_autocmd('BufRead', { - callback = function() - vim.cmd[[ silent! foldclose! ]] - local bufnr = vim.api.nvim_get_current_buf() - -- make sure buffer is attached - vim.wait(100, function() require'ufo'.attach(bufnr) end) - if require'ufo'.hasAttached(bufnr) then - local winid = vim.api.nvim_get_current_win() - local method = vim.wo[winid].foldmethod - if method == 'diff' or method == 'marker' then - require'ufo'.closeAllFolds() - return - end - -- getFolds returns a Promise if providerName == 'lsp', use vim.wait in this case - local ok, ranges = pcall(require'ufo'.getFolds, bufnr, 'treesitter') - if ok and ranges then - if require'ufo'.applyFolds(bufnr, ranges) then - pcall(require'ufo'.closeAllFolds) - end - end - end - end + ---}}} + + ---surround {{{ + -- surround text with pairs of elements + use({ + "tpope/vim-surround", + require = { "tpope/vim-repeat" }, + config = function() + vim.g.surround_no_mappings = 1 + vim.api.nvim_set_keymap("n", "ds", "Dsurround", { noremap = true }) + vim.api.nvim_set_keymap("n", "cs", "Csurround", { noremap = true }) + vim.api.nvim_set_keymap("n", "ys", "Ysurround", { noremap = true }) + vim.api.nvim_set_keymap("n", "yS", "YSurround", { noremap = true }) + vim.api.nvim_set_keymap("n", "yss", "Yssurround", { noremap = true }) + vim.api.nvim_set_keymap("n", "ySS", "YSsurround", { noremap = true }) + vim.api.nvim_set_keymap("x", "Y", "VSurround", { noremap = true }) + vim.api.nvim_set_keymap("x", "gY", "VgSurround", { noremap = true }) + vim.api.nvim_set_keymap("i", "", "Isurround", { noremap = true }) + -- surrounds text with escaped delimiters `\` (char 92), e.g. foo -> \( foo \) + -- prompts for delimiter with `\1delimiter: \1` + -- replaces first character `\r^.\r\\\\&` and removes second character `\r.$\r` + -- removes first character `\r^.\r` and replaces second character `\r.$\r\\\\&` + -- see manual for more details :help surround-customizing + vim.g.surround_92 = "\1delimiter: \r^.\r\\\\&\r.$\r\1 \r \1\r^.\r\r.$\r\\\\&\1" + end, }) - end - } - ---}}} - - ---surround {{{ - -- surround text with pairs of elements - use { - 'tpope/vim-surround', - require = { 'tpope/vim-repeat' }, - config = function() - vim.g.surround_no_mappings = 1 - vim.api.nvim_set_keymap('n', 'ds', 'Dsurround', { noremap = true }) - vim.api.nvim_set_keymap('n', 'cs', 'Csurround', { noremap = true }) - vim.api.nvim_set_keymap('n', 'ys', 'Ysurround', { noremap = true }) - vim.api.nvim_set_keymap('n', 'yS', 'YSurround', { noremap = true }) - vim.api.nvim_set_keymap('n', 'yss', 'Yssurround', { noremap = true }) - vim.api.nvim_set_keymap('n', 'ySS', 'YSsurround', { noremap = true }) - vim.api.nvim_set_keymap('x', 'Y', 'VSurround', { noremap = true }) - vim.api.nvim_set_keymap('x', 'gY', 'VgSurround', { noremap = true }) - vim.api.nvim_set_keymap('i', '', 'Isurround', { noremap = true }) - -- surrounds text with escaped delimiters `\` (char 92), e.g. foo -> \( foo \) - -- prompts for delimiter with `\1delimiter: \1` - -- replaces first character `\r^.\r\\\\&` and removes second character `\r.$\r` - -- removes first character `\r^.\r` and replaces second character `\r.$\r\\\\&` - -- see manual for more details :help surround-customizing - vim.g.surround_92 = "\1delimiter: \r^.\r\\\\&\r.$\r\1 \r \1\r^.\r\r.$\r\\\\&\1" - end - - } - ---}}} - - ---matchit {{{ - -- extended % matching for HTML, Latex and many other languages - use { 'vim-scripts/matchit.zip' } - ---}}} - - ---rename {{{ - -- rename files in vim - use { 'danro/rename.vim' } - ---}}} - - ---pencil {{{ - -- rethinking Vim as a tool for writing - use { - 'gzagatti/vim-pencil', - config = function () - vim.g['pencil#conceallevel'] = 0 - vim.g['pencil#concealcursor'] = 'c' - vim.cmd [[ + ---}}} + + ---matchit {{{ + -- extended % matching for HTML, Latex and many other languages + use({ "vim-scripts/matchit.zip" }) + ---}}} + + ---rename {{{ + -- rename files in vim + use({ "danro/rename.vim" }) + ---}}} + + ---pencil {{{ + -- rethinking Vim as a tool for writing + use({ + "gzagatti/vim-pencil", + config = function() + vim.g["pencil#conceallevel"] = 0 + vim.g["pencil#concealcursor"] = "c" + vim.cmd([[ augroup pencil autocmd! - autocmd FileType tex,org,typst,markdown call pencil#init({'wrap': 'soft'}) + autocmd FileType tex,org,typst call pencil#init({'wrap': 'soft'}) augroup END - ]] - end - } - ---}}} - - ---goyo{{{ - -- distraction free-writing in Vim - use { - 'junegunn/goyo.vim', - config = function () - vim.g.goyo_width = "120" - vim.g.goyo_height = "90%" - vim.api.nvim_set_keymap('n', 'go', 'Goyo', { noremap = true }) - vim.cmd [[ + ]]) + end, + }) + ---}}} + + ---goyo{{{ + -- distraction free-writing in Vim + use({ + "junegunn/goyo.vim", + config = function() + vim.g.goyo_width = "120" + vim.g.goyo_height = "90%" + vim.api.nvim_set_keymap("n", "go", "Goyo", { noremap = true }) + vim.cmd([[ function! s:GoyoEnter() if executable('tmux') && strlen($TMUX) silent !tmux set -w status off @@ -986,652 +1161,551 @@ require'packer'.startup {function (use) autocmd! User GoyoEnter nested call GoyoEnter() autocmd! User GoyoLeave nested call GoyoLeave() - ]] - end - } - ---}}} - - ---easy align {{{ - -- vim alignment - use { 'junegunn/vim-easy-align' } - ---}}} - - ---orgmode {{{ - -- orgmode clone written in Lua - use { - here 'orgmode', - requires = { 'nvim-treesitter/nvim-treesitter' }, - config = function () - require'orgmode'.setup_ts_grammar() - require'orgmode'.setup { - org_startup_indented = false, - mappings = { - org = { - org_do_promote = '}) ]] - end - } - ---}}} - - ---cmp {{{ - -- auto-completion for nvim written in Lua - use { - 'hrsh7th/nvim-cmp', - requires = { - 'hrsh7th/cmp-nvim-lsp', - 'hrsh7th/cmp-buffer', - 'hrsh7th/cmp-path', - 'hrsh7th/cmp-cmdline', - 'hrsh7th/vim-vsnip', - 'hrsh7th/cmp-vsnip', - 'gzagatti/cmp-latex-symbols', - 'hrsh7th/cmp-nvim-lua', - 'jmbuhr/otter.nvim', - here 'cmp-copilot', - }, - config = function () - - vim.g.vsnip_snippet_dir = vim.env.HOME.."/.config/nvim/vsnip" + end, + }) + vim.cmd( + [[ command! -nargs=* -complete=customlist,v:lua.otter_extensions LspOtter lua require'otter'.activate({}) ]] + ) + end, + }) + ---}}} + + ---cmp {{{ + -- auto-completion for nvim written in Lua + use({ + "hrsh7th/nvim-cmp", + requires = { + "hrsh7th/cmp-nvim-lsp", + "hrsh7th/cmp-buffer", + "hrsh7th/cmp-path", + "hrsh7th/cmp-cmdline", + "hrsh7th/vim-vsnip", + "hrsh7th/cmp-vsnip", + "gzagatti/cmp-latex-symbols", + "hrsh7th/cmp-nvim-lua", + "jmbuhr/otter.nvim", + -- 'gzagatti/cmp-copilot', + }, + config = function() + vim.g.vsnip_snippet_dir = vim.env.HOME .. "/.config/nvim/vsnip" - local cmp = require'cmp' + local cmp = require("cmp") - -- https://github.com/hrsh7th/nvim-cmp/wiki/Example-mappings - local has_words_before = function() - if vim.api.nvim_buf_get_option(0, "buftype") == "prompt" then return false end - local line, col = unpack(vim.api.nvim_win_get_cursor(0)) - return col ~= 0 and vim.api.nvim_buf_get_text(0, line-1, 0, line-1, col, {})[1]:match("^%s*$") == nil - end + -- https://github.com/hrsh7th/nvim-cmp/wiki/Example-mappings + local has_words_before = function() + if vim.api.nvim_buf_get_option(0, "buftype") == "prompt" then + return false + end + local line, col = unpack(vim.api.nvim_win_get_cursor(0)) + return col ~= 0 and vim.api.nvim_buf_get_text(0, line - 1, 0, line - 1, col, {})[1]:match("^%s*$") == nil + end - local feedkey = function (key, mode) - vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(key, true, true, true), mode, true) - end + local feedkey = function(key, mode) + vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(key, true, true, true), mode, true) + end - cmp.setup { - snippet = { - expand = function(args) - vim.fn["vsnip#anonymous"](args.body) - end, - }, - mapping = { - [""] = cmp.mapping( - function(fallback) - if cmp.visible() and has_words_before() then - cmp.select_next_item({ behavior = cmp.SelectBehavior }) - else - fallback() - end - end, - { "i", "s" } - ), - [""] = cmp.mapping( - function() - if cmp.visible() then - cmp.select_prev_item({ behavior = cmp.SelectBehavior }) - end - end, - { "i", "s" } - ), - [""] = cmp.mapping.confirm { select = true }, - [""] = cmp.mapping.complete(), - [""] = cmp.mapping( - function(fallback) - if cmp.visible() and has_words_before() then - cmp.abort() - else - fallback() - end - end, - { "i", "s" } - ), - [""] = cmp.mapping( - function(fallback) - if cmp.visible() and has_words_before() then - cmp.abort() - else - fallback() + cmp.setup({ + snippet = { + expand = function(args) + vim.fn["vsnip#anonymous"](args.body) + end, + }, + mapping = { + [""] = cmp.mapping(function(fallback) + if cmp.visible() and has_words_before() then + cmp.select_next_item({ behavior = cmp.SelectBehavior }) + else + fallback() + end + end, { "i", "s" }), + [""] = cmp.mapping(function() + if cmp.visible() then + cmp.select_prev_item({ behavior = cmp.SelectBehavior }) + end + end, { "i", "s" }), + [""] = cmp.mapping.confirm({ select = true }), + [""] = cmp.mapping.complete(), + [""] = cmp.mapping(function(fallback) + if cmp.visible() and has_words_before() then + cmp.abort() + else + fallback() + end + end, { "i", "s" }), + [""] = cmp.mapping(function(fallback) + if cmp.visible() and has_words_before() then + cmp.abort() + else + fallback() + end + end, { "i", "s" }), + }, + sources = cmp.config.sources({ + { name = "vsnip" }, + { name = "nvim_lsp" }, + { name = "otter" }, + { name = "path" }, + { name = "nvim_lua" }, + -- override trigger characters, so they don't interfere with snippets + { name = "orgmode", trigger_characters = {} }, + { name = "latex_symbols" }, + { name = "buffer", keyword_length = 3 }, + { name = "copilot" }, + }), + }) + + -- use arrows to navigate through snippet fields + vim.api.nvim_set_keymap( + "i", + "", + 'vsnip#jumpable(1) ? "(vsnip-jump-next)" : ""', + { expr = true, noremap = true } + ) + vim.api.nvim_set_keymap( + "s", + "", + 'vsnip#jumpable(1) ? "(vsnip-jump-next)" : ""', + { expr = true, noremap = true } + ) + vim.api.nvim_set_keymap( + "i", + "", + 'vsnip#jumpable(-1) ? "(vsnip-jump-prev)" : ""', + { expr = true, noremap = true } + ) + vim.api.nvim_set_keymap( + "s", + "", + 'vsnip#jumpable(-1) ? "(vsnip-jump-prev)" : ""', + { expr = true, noremap = true } + ) + + function cmp_sources_list(arglead, _, _) + -- the API does not allow for the retrieval of sources from cmdline + local global_sources = require("cmp.config").global.sources + local out = {} + for i = 1, #global_sources do + if global_sources[i].name:find("^" .. arglead) ~= nil then + out[#out + 1] = global_sources[i].name end - end, - { "i", "s" } - ), - }, - sources = cmp.config.sources({ - { name = 'vsnip' }, - { name = 'nvim_lsp' }, - { name = 'otter' }, - { name = 'path' }, - { name = 'nvim_lua' }, - -- override trigger characters, so they don't interfere with snippets - { name = 'orgmode', trigger_characters = {} }, - { name = 'latex_symbols' }, - { name = 'buffer', keyword_length = 3 }, - { name = 'copilot' }, - }), - } - - -- use arrows to navigate through snippet fields - vim.api.nvim_set_keymap('i', '', 'vsnip#jumpable(1) ? "(vsnip-jump-next)" : ""', { expr = true, noremap = true }) - vim.api.nvim_set_keymap('s', '', 'vsnip#jumpable(1) ? "(vsnip-jump-next)" : ""', { expr = true, noremap = true }) - vim.api.nvim_set_keymap('i', '', 'vsnip#jumpable(-1) ? "(vsnip-jump-prev)" : ""', { expr = true, noremap = true }) - vim.api.nvim_set_keymap('s', '', 'vsnip#jumpable(-1) ? "(vsnip-jump-prev)" : ""', { expr = true, noremap = true }) - - function cmp_sources_list(arglead, _, _) - -- the API does not allow for the retrieval of sources from cmdline - local global_sources = require'cmp.config'.global.sources - local out = {} - for i = 1,#global_sources do - if global_sources[i].name:find("^" .. arglead) ~= nil then - out[#out + 1] = global_sources[i].name + end + return out end - end - return out - end - function disable_cmp_source(name) - local current_sources = cmp.get_config().sources - local new_sources = {} - for i = 1,#current_sources do - if current_sources[i].name ~= name then - new_sources[i] = current_sources[i] + function disable_cmp_source(name) + local current_sources = cmp.get_config().sources + local new_sources = {} + for i = 1, #current_sources do + if current_sources[i].name ~= name then + new_sources[i] = current_sources[i] + end end + cmp.setup.buffer({ sources = new_sources }) end - cmp.setup.buffer({sources = new_sources}) - end - function enable_cmp_source(name) - local global_sources = require'cmp.config'.global.sources - local new_sources = cmp.get_config().sources - for i = 1,#global_sources do - if global_sources[i].name == name then - new_sources[#new_sources+1] = global_sources[i] + function enable_cmp_source(name) + local global_sources = require("cmp.config").global.sources + local new_sources = cmp.get_config().sources + for i = 1, #global_sources do + if global_sources[i].name == name then + new_sources[#new_sources + 1] = global_sources[i] + end end + cmp.setup.buffer({ sources = new_sources }) end - cmp.setup.buffer({sources = new_sources}) - end - - vim.cmd [[ command! -nargs=1 -complete=customlist,v:lua.cmp_sources_list CmpDisable lua disable_cmp_source() ]] - vim.cmd [[ command! -nargs=1 -complete=customlist,v:lua.cmp_sources_list CmpEnable lua enable_cmp_source() ]] - - end - } - ---}}} - - ---gnupg {{{ - -- easy gpg handling - use { - 'jamessan/vim-gnupg', - config = function () vim.g['GPGPreferSymmetric'] = 1 end - } - ---}}} - - ---emmet {{{ - -- improves HTML and CSS workflow - use { - 'mattn/emmet-vim', - ft = {'html', 'css'} - } - ---}}} - - ---asciidoctor {{{ - -- asciidoctor support - use { - 'habamax/vim-asciidoctor', - config = function () - - vim.g['asciidoctor_folding'] = 1 - vim.g['asciidoctor_fold_options'] = 1 - vim.g['asciidoctor_fenced_languages'] = { 'sh', 'css' } - vim.g['asciidoctor_extensions'] = { 'asciidoctor-tufte', 'asciidoctor-bibtex' } - vim.g['asciidoctor_autocompile'] = 0 - - vim.cmd [[ - function! s:ToggleAsciidoctorAutocompile() - augroup asciidoctor - autocmd! - if g:asciidoctor_autocompile == 0 - autocmd BufWritePost *.adoc :execute "silent normal! mq" ':Asciidoctor2HTML' "\r`q" - endif - augroup END - if g:asciidoctor_autocompile == 0 - let g:asciidoctor_autocompile = 1 - echo "asciidoctor: Compiler started in continuous mode" - else - let g:asciidoctor_autocompile = 0 - echo "asciidoctor: Compiler stopped" - endif - endfunction - ]] - end - } - ---}}} - - ---sniprun {{{ - -- run lines/blocs of code (independently of the rest of the file) - use { - 'michaelb/sniprun', - run = "sh ./install.sh 1", - config = function () - require'sniprun'.setup { - repl_enable = {'Python3_jupyter', 'Julia_jupyter'}, - interpreter_options = { - Python3_original = { - interpreter = 'python', - }, - Julia_original = { - interpreter = 'julia', - }, - }, - } - end - } - ---}}} - - ---luadev {{{ - -- REPL/debug console for nvim - use { - -- 'bfredl/nvim-luadev', - here 'nvim-luadev', - config = function () - vim.api.nvim_set_keymap('n', 'ee', '(Luadev-RunLine):Luadev', { silent= true }) - vim.api.nvim_set_keymap('v', 'ee', '(Luadev-Run):Luadev', { silent=true }) - vim.api.nvim_set_keymap('n', 'ev', '(Luadev-RunVimLine):Luadev', { silent= true }) - vim.api.nvim_set_keymap('v', 'ev', '(Luadev-RunVim):Luadev', { silent= true }) - end - } - ---}}} - ---minimap {{{ - -- a dotted minimap of the file - use { - 'wfxr/minimap.vim', - config = function () - vim.g ['minimap_auto_start'] = 0 - vim.g ['minimap_auto_start_win_enter'] = 0 - vim.api.nvim_set_keymap('n', '', ':MinimapToggle', { noremap = true }) - end - } - ---}}} - - ---fugitive {{{ - use { - 'tpope/vim-fugitive' - } - ---}}} - - ---spotdiff {{{ - use { - 'rickhowe/spotdiff.vim' - } - ---}}} + vim.cmd( + [[ command! -nargs=1 -complete=customlist,v:lua.cmp_sources_list CmpDisable lua disable_cmp_source() ]] + ) + vim.cmd( + [[ command! -nargs=1 -complete=customlist,v:lua.cmp_sources_list CmpEnable lua enable_cmp_source() ]] + ) + end, + }) + ---}}} + + ---gnupg {{{ + -- easy gpg handling + use({ + "jamessan/vim-gnupg", + config = function() + vim.g["GPGPreferSymmetric"] = 1 + end, + }) + ---}}} - ---diffchar {{{ - use { - 'rickhowe/diffchar.vim' - } - ---}}} + ---emmet {{{ + -- improves HTML and CSS workflow + use({ + "mattn/emmet-vim", + ft = { "html", "css" }, + }) + ---}}} + + ---sniprun {{{ + -- run lines/blocs of code (independently of the rest of the file) + use({ + "michaelb/sniprun", + run = "bash ./install.sh 1", + config = function() + require("sniprun").setup({ + repl_enable = { "Python3_jupyter", "Julia_jupyter" }, + interpreter_options = { + Python3_original = { + interpreter = "python", + }, + Julia_original = { + interpreter = "julia", + }, + }, + }) + end, + }) + ---}}} + + ---luadev {{{ + -- REPL/debug console for nvim + use({ + -- 'bfredl/nvim-luadev', + "gzagatti/nvim-luadev", + config = function() + vim.api.nvim_set_keymap("n", "ee", "(Luadev-RunLine):Luadev", { silent = true }) + vim.api.nvim_set_keymap("v", "ee", "(Luadev-Run):Luadev", { silent = true }) + vim.api.nvim_set_keymap("n", "ev", "(Luadev-RunVimLine):Luadev", { silent = true }) + vim.api.nvim_set_keymap("v", "ev", "(Luadev-RunVim):Luadev", { silent = true }) + end, + }) + ---}}} - ---aerial {{{ - -- code outline window - use { - 'stevearc/aerial.nvim', - config = function() - require'aerial'.setup({ - layout = { - placement = "edge", - default_direction = "right", - }, - attach_mode = "global", - keymaps = { - [""] = "actions.scroll", - } + ---fugitive {{{ + use({ + "tpope/vim-fugitive", }) - vim.api.nvim_set_keymap('n', '', 'AerialToggle! right', { noremap = true }) - end - } - ---}}} + ---}}} - ---hologram {{{ - -- image viewer for Neovim - -- use { - -- here 'hologram.nvim', - -- config = function() - -- require'hologram'.setup() - -- end, - -- } - ---}}} + ---spotdiff {{{ + use({ + "rickhowe/spotdiff.vim", + }) + ---}}} - ---clipboard image {{{ - -- paste image from clipboard - use { - here 'clipboard-image.nvim', - config = function() - - local function uuid_name() - local img_dir = vim.fn.expand("%:p:h") .. "/assets" - img_dir = io.popen('ls "'..img_dir..'" 2>/dev/null') - local files = {} - if img_dir ~= nil then - for filename in img_dir:lines() do - filename = filename:match("(.+)%..+$") - if filename ~= nil then files[filename] = true end + ---diffchar {{{ + use({ + "rickhowe/diffchar.vim", + }) + ---}}} + + ---aerial {{{ + -- code outline window + use({ + "stevearc/aerial.nvim", + config = function() + require("aerial").setup({ + layout = { + placement = "edge", + default_direction = "right", + }, + attach_mode = "global", + keymaps = { + [""] = "actions.scroll", + }, + }) + vim.api.nvim_set_keymap("n", "", "AerialToggle! right", { noremap = true }) + end, + }) + ---}}} + + ---clipboard image {{{ + -- paste image from clipboard + use({ + "gzagatti/clipboard-image.nvim", + config = function() + local function uuid_name() + local img_dir = vim.fn.expand("%:p:h") .. "/assets" + img_dir = io.popen('ls "' .. img_dir .. '" 2>/dev/null') + local files = {} + if img_dir ~= nil then + for filename in img_dir:lines() do + filename = filename:match("(.+)%..+$") + if filename ~= nil then + files[filename] = true + end + end + img_dir.close() + end + repeat + uuid = vim.fn.call("system", { "uuidgen" }):sub(10, 13) + until files[uuid] == nil + return uuid end - img_dir.close() - end - repeat - uuid = vim.fn.call("system", {"uuidgen"}):sub(10, 13) - until files[uuid] == nil - return uuid - end - - local function resize(img) - os.execute(string.format( - 'mogrify -quality 95 -resize "600x400>" "%s"', - img.path - )) - end - require'clipboard-image'.setup { - default = { - img_dir = {"%:p:h"}, - img_dir_txt = ".", - }, - org = { - img_dir = {"%:p:h", "assets"}, - img_dir_txt = "./assets", - img_name = uuid_name, - affix = "[[%s]]", - img_handler = resize, - }, - tex = { - img_dir = {"%:p:h", "assets"}, - img_dir_txt = "./assets", - img_name = uuid_name, - affix = "\\includegraphics{%s}", - img_handler = resize, - } - } - - vim.api.nvim_create_user_command( - 'PastePNG', - function(opts) require'clipboard-image.paste'.paste_img({img_format='png'}) end, - { nargs = 0 } - ) - vim.api.nvim_create_user_command( - 'PasteJPG', - function(opts) require'clipboard-image.paste'.paste_img({img_format='jpg'}) end, - { nargs = 0 } - ) - vim.api.nvim_create_user_command( - 'PasteWEBP', - function(opts) require'clipboard-image.paste'.paste_img({img_format='webp'}) end, - { nargs = 0 } - ) - - end, - } - --}}} - - ---nabla {{{ - -- equation rendering - -- TODO support LaTex equations - -- TODO support visual selection - -- use { - -- 'jbyuki/nabla.nvim', - -- config = function() - -- vim.api.nvim_set_keymap('n', 'gE', "lua require'nabla'.popup()", { noremap=true }) - -- end, - -- } - --}}} - - ---beancount {{{ - -- support for beancount files - use { 'nathangrigg/vim-beancount' } - --}}} - - ---drawit {{{ - -- ASCII drawing plugin - use { 'vim-scripts/DrawIt' } - --}}} - - ---venn {{{ - -- draw ASCII diagrams - use { 'jbyuki/venn.nvim' } - --}}} - - ---chatgpt {{{ - -- ChatGPT - use { - 'jackMort/ChatGPT.nvim', - requires = { - 'MunifTanjim/nui.nvim', - 'nvim-lua/plenary.nvim', - 'nvim-telescope/telescope.nvim' - }, - config = function () - require'chatgpt'.setup({ - api_key_cmd = "secret-tool lookup application chatgpt" - }) - end - } - ---}}} + local function resize(img) + os.execute(string.format('mogrify -quality 95 -resize "600x400>" "%s"', img.path)) + end - ---copilot {{{ - -- Github copilot - use { - 'github/copilot.vim', - requires = { here 'cmp-copilot' }, - cmd = "Copilot", - config = function() - vim.g.copilot_no_tab_map = true - vim.g.copilot_filetypes = { ['*'] = false } - vim.api.nvim_set_keymap('n', 'co', ':Copilot panel', { noremap = true }) - vim.api.nvim_create_autocmd('FileType', { - pattern = { "copilot.*" }, - callback = function() - vim.api.nvim_buf_set_keymap(0, 'n', 'q', ':q', { noremap = true, nowait = true }) + require("clipboard-image").setup({ + default = { + img_dir = { "%:p:h" }, + img_dir_txt = ".", + }, + org = { + img_dir = { "%:p:h", "assets" }, + img_dir_txt = "./assets", + img_name = uuid_name, + affix = "[[%s]]", + img_handler = resize, + }, + tex = { + img_dir = { "%:p:h", "assets" }, + img_dir_txt = "./assets", + img_name = uuid_name, + affix = "\\includegraphics{%s}", + img_handler = resize, + }, + }) + + vim.api.nvim_create_user_command("PastePNG", function(opts) + require("clipboard-image.paste").paste_img({ img_format = "png" }) + end, { nargs = 0 }) + vim.api.nvim_create_user_command("PasteJPG", function(opts) + require("clipboard-image.paste").paste_img({ img_format = "jpg" }) + end, { nargs = 0 }) + vim.api.nvim_create_user_command("PasteWEBP", function(opts) + require("clipboard-image.paste").paste_img({ img_format = "webp" }) + end, { nargs = 0 }) end, }) - end - } - ---}}} - - ---leetbuddy {{{ - -- solve leetcode problems from neovim - use { - 'Dhanus3133/LeetBuddy.nvim', - cmd = { "LBCheckCookies", "LBQuestions", "LBQuestion" }, - requires = { - 'nvim-lua/plenary.nvim', - 'nvim-telescope/telescope.nvim', - }, - config = function() - require'leetbuddy'.setup({}) - end - } - ---}}} - - ---mini.indentscope {{{ - -- visualize scope with animated vertical line - use { - 'echasnovski/mini.indentscope', - config = function() - require'mini.indentscope'.setup({ - draw = { - animation = require'mini.indentscope'.gen_animation.none(), - }, - options = { - border = 'top' - } - }) - vim.api.nvim_create_autocmd('ColorScheme', { - pattern = {"leuven"}, - command = [[highlight MiniIndentscopeSymbol guifg='#dadad7' ctermfg=253]] - }) - vim.api.nvim_create_autocmd('ColorScheme', { - pattern = {"dracula"}, - command = [[highlight MiniIndentscopeSymbol guifg='#2f3751' ctermfg=253]] - }) - vim.api.nvim_create_autocmd('FileType', { - pattern = {"help", "aerial"}, - callback = function() - vim.b.miniindentscope_disable = true - end, - }) - end - } - ---}}} - - ---theme: dracula {{{ - use { - 'dracula/vim', - after = { 'mini.indentscope' }, - config = function () - if (vim.env.THEME == 'dracula') or (vim.env.THEME == nil) then - vim.cmd [[ + --}}} + + ---drawit {{{ + -- ASCII drawing plugin + use({ "vim-scripts/DrawIt" }) + --}}} + + ---venn {{{ + -- draw ASCII diagrams + use({ "jbyuki/venn.nvim" }) + --}}} + + -- ---chatgpt {{{ + -- -- ChatGPT + -- use { + -- 'jackMort/ChatGPT.nvim', + -- requires = { + -- 'MunifTanjim/nui.nvim', + -- 'nvim-lua/plenary.nvim', + -- 'nvim-telescope/telescope.nvim' + -- }, + -- config = function () + -- require'chatgpt'.setup({ + -- api_key_cmd = "secret-tool lookup application chatgpt" + -- }) + -- end + -- } + -- ---}}} + + -- ---copilot {{{ + -- -- Github copilot + -- use { + -- 'github/copilot.vim', + -- requires = { 'gzagatti/cmp-copilot' }, + -- cmd = "Copilot", + -- config = function() + -- vim.g.copilot_no_tab_map = true + -- vim.g.copilot_filetypes = { ['*'] = false } + -- vim.api.nvim_set_keymap('n', 'co', ':Copilot panel', { noremap = true }) + -- vim.api.nvim_create_autocmd('FileType', { + -- pattern = { "copilot.*" }, + -- callback = function() + -- vim.api.nvim_buf_set_keymap(0, 'n', 'q', ':q', { noremap = true, nowait = true }) + -- end, + -- }) + -- end + -- } + -- ---}}} + + ---mini.indentscope {{{ + -- visualize scope with animated vertical line + use({ + "echasnovski/mini.indentscope", + config = function() + require("mini.indentscope").setup({ + draw = { + animation = require("mini.indentscope").gen_animation.none(), + }, + options = { + border = "top", + }, + }) + vim.api.nvim_create_autocmd("ColorScheme", { + pattern = { "leuven" }, + command = [[highlight MiniIndentscopeSymbol guifg='#dadad7' ctermfg=253]], + }) + vim.api.nvim_create_autocmd("ColorScheme", { + pattern = { "dracula" }, + command = [[highlight MiniIndentscopeSymbol guifg='#2f3751' ctermfg=253]], + }) + vim.api.nvim_create_autocmd("FileType", { + pattern = { "help", "aerial" }, + callback = function() + vim.b.miniindentscope_disable = true + end, + }) + end, + }) + ---}}} + + ---theme: dracula {{{ + use({ + "dracula/vim", + -- after = { "mini.indentscope" }, + config = function() + if (vim.env.THEME == "dracula") or (vim.env.THEME == nil) then + vim.cmd([[ colorscheme dracula - ]] - end - end - } - ---}}} - - ---theme: leuven {{{ - use { - here 'vim-leuven-theme', - after = { 'mini.indentscope' }, - config = function () - if (vim.env.THEME == 'leuven') then - vim.cmd [[ + ]]) + end + end, + }) + ---}}} + + ---theme: leuven {{{ + use({ + "gzagatti/vim-leuven-theme", + after = { "mini.indentscope" }, + config = function() + if vim.env.THEME == "leuven" then + vim.cmd([[ colorscheme leuven - ]] - end - end - } - ---}}} - - end, - config = { - package_root = package_root, - compile_path = compile_path, - auto_clean = true, - }, -} + ]]) + end + end, + }) + ---}}} + end, + config = { + package_root = package_root, + compile_path = compile_path, + auto_clean = true, + }, + }) end --}}} --config {{{ _G.load_config = function() - ---basic settings {{{ + --basic settings {{{ ---basic {{{ - vim.opt.encoding = 'utf-8' + vim.opt.encoding = "utf-8" vim.opt.lazyredraw = true + vim.opt.more = false ---}}} ---colors {{{ vim.opt.termguicolors = true - vim.opt.guicursor = 'a:blinkon0-Cursor,i-ci:ver100' + vim.opt.guicursor = "a:blinkon0-Cursor,i-ci:ver100" ---}}} ---leaders {{{ - vim.g.mapleader = ';' - vim.g.maplocalleader = '\\' + vim.g.mapleader = ";" + vim.g.maplocalleader = "#" --}}} ---mouse {{{ - if vim.fn.has('mouse') then - vim.opt.mouse= 'nv' + if vim.fn.has("mouse") then + vim.opt.mouse = "nv" -- do not move cursor with arrows in insert - vim.api.nvim_set_keymap('i', '', '', { noremap = true }) - vim.api.nvim_set_keymap('i', '', '', { noremap = true }) - vim.api.nvim_set_keymap('i', '', '', { noremap = true }) - vim.api.nvim_set_keymap('i', '', '', { noremap = true }) + vim.api.nvim_set_keymap("i", "", "", { noremap = true }) + vim.api.nvim_set_keymap("i", "", "", { noremap = true }) + vim.api.nvim_set_keymap("i", "", "", { noremap = true }) + vim.api.nvim_set_keymap("i", "", "", { noremap = true }) end ---}}} ---autocompletion {{{ vim.opt.wildmenu = true -- autocomplete feature when cycling through TAB - vim.opt.wildmode = 'longest:full,full' + vim.opt.wildmode = "longest:full,full" vim.opt.wildignorecase = true - vim.opt.completeopt = 'menu,menuone,noselect' + vim.opt.completeopt = "menu,menuone,noselect" ---}}} ---line ruler {{{ @@ -1652,16 +1726,16 @@ _G.load_config = function() vim.opt.shiftwidth = 0 -- if vartabstop is set then tabstop is ignored and vartabstop is used instead -- the number of spaces that a in the file counts for - vim.opt.vartabstop = '2' + vim.opt.vartabstop = "2" -- if varsofttabstop is set then softtabstop is ignored and varsofttabstop is used instead -- softtabstop will mix space and tabs in a file that uses tab. For those using -- expandtab = true softtabstop will ensure that works by deleting the -- equivalet number of tabs - vim.opt.varsofttabstop = '2' - vim.opt.backspace = 'indent,eol,start' + vim.opt.varsofttabstop = "2" + vim.opt.backspace = "indent,eol,start" vim.opt.list = true - vim.opt.listchars = { tab = '»·', trail = '·', extends = '›', precedes = '‹', nbsp = '␣'} - vim.opt.fillchars = { fold = '.' } + vim.opt.listchars = { tab = "»·", trail = "·", extends = "›", precedes = "‹", nbsp = "␣" } + vim.opt.fillchars = { fold = "." } --}}} ---folding {{{ @@ -1679,28 +1753,28 @@ _G.load_config = function() ---}}} ---buffers {{{ - vim.opt.switchbuf = 'useopen' + vim.opt.switchbuf = "useopen" vim.opt.autowriteall = true vim.opt.autoread = true - vim.cmd [[ + vim.cmd([[ autocmd FocusGained,CursorHold * if getcmdwintype() == '' | checktime | endif - ]] + ]]) ---}}} ---backup and swap files {{{ - vim.opt.backupdir = vim.env.HOME .. '/.local/share/nvim/swap' -- backup files - vim.opt.directory = vim.env.HOME .. '/.local/share/nvim/swap' -- swap files + vim.opt.backupdir = vim.env.HOME .. "/.local/share/nvim/swap" -- backup files + vim.opt.directory = vim.env.HOME .. "/.local/share/nvim/swap" -- swap files ---}}} ---tags {{{ - vim.opt.tags='.git/tags,tags,./tags' + vim.opt.tags = ".git/tags,tags,./tags" ---}}} ---sign column {{{ - vim.cmd [[ + vim.cmd([[ highlight SignColumn ctermbg=NONE guibg=NONE - ]] - vim.opt.signcolumn = 'number' + ]]) + vim.opt.signcolumn = "number" ---}}} ---status line {{{ @@ -1708,16 +1782,16 @@ _G.load_config = function() ---}}} ---auto save {{{ - vim.cmd [[ + vim.cmd([[ augroup auto_save autocmd! au CursorHold,InsertLeave * silent! wall augroup END - ]] + ]]) ---}}} ---newtrw{{{ - vim.cmd [[ + vim.cmd([[ let g:netrw_browsex_viewer= "-" function! s:myNFH(filename) if executable("xdg-open") @@ -1746,66 +1820,66 @@ _G.load_config = function() function! NFH_pdf(filename) call s:myNFH(a:filename) endfunction - ]] + ]]) ---}}} ---filetype plugins {{{ - vim.cmd [[ + vim.cmd([[ filetype plugin indent on - ]] + ]]) ---}}} ---providers {{{ -- python - vim.g['loaded_python_provider'] = 0 - vim.g['python3_host_prog'] = vim.env.HOME .. "/.pyenv/versions/vim3/bin/python" + vim.g["loaded_python_provider"] = 0 + vim.g["python3_host_prog"] = vim.env.HOME .. "/.pyenv/versions/vim3/bin/python" -- ruby - vim.g['loaded_ruby_provider'] = 0 + vim.g["loaded_ruby_provider"] = 0 --perl - vim.g['loaded_perl_provider'] = 0 + vim.g["loaded_perl_provider"] = 0 ---}}} ---terminal {{{ - vim.api.nvim_set_keymap('t', '', 'h', { noremap = true }) - vim.api.nvim_set_keymap('t', '', 'j', { noremap = true }) - vim.api.nvim_set_keymap('t', '', 'k', { noremap = true }) - vim.api.nvim_set_keymap('t', '', 'l', { noremap = true }) - vim.cmd [[ + vim.api.nvim_set_keymap("t", "", "h", { noremap = true }) + vim.api.nvim_set_keymap("t", "", "j", { noremap = true }) + vim.api.nvim_set_keymap("t", "", "k", { noremap = true }) + vim.api.nvim_set_keymap("t", "", "l", { noremap = true }) + vim.cmd([[ au TermOpen * setlocal nonumber - ]] + ]]) ---}}} ---quickfix {{{ - vim.cmd[[packadd cfilter]] + vim.cmd([[packadd cfilter]]) ---}}} ---}}} + --}}} ---key mappings {{{ + --key mappings {{{ ---.vimrc {{{ --open .vimrc in a horizantal split$ - vim.api.nvim_set_keymap('n', '', ':split $MYVIMRC', { noremap = true }) - vim.api.nvim_set_keymap('n', '', ':source $MYVIMRC:PackerCompile', { noremap = true }) + vim.api.nvim_set_keymap("n", "", ":split $MYVIMRC", { noremap = true }) + vim.api.nvim_set_keymap("n", "", ":source $MYVIMRC:PackerCompile", { noremap = true }) ---}}} ---map j and k such that is based on display lines, not physical ones {{{ - vim.api.nvim_set_keymap('', 'j', 'gj', { noremap = true }) - vim.api.nvim_set_keymap('', 'k', 'gk', { noremap = true }) - if (vim.g['kitty_navigator_no_mappings'] == 1) and (vim.g['tmux_navigator_no_mappings'] == 1) then - vim.api.nvim_set_keymap('', '', 'wincmd h', { noremap = true }) - vim.api.nvim_set_keymap('', '', 'wincmd j', { noremap = true }) - vim.api.nvim_set_keymap('', '', 'wincmd k', { noremap = true }) - vim.api.nvim_set_keymap('', '', 'wincmd l', { noremap = true }) + vim.api.nvim_set_keymap("", "j", "gj", { noremap = true }) + vim.api.nvim_set_keymap("", "k", "gk", { noremap = true }) + if (vim.g["kitty_navigator_no_mappings"] == 1) and (vim.g["tmux_navigator_no_mappings"] == 1) then + vim.api.nvim_set_keymap("", "", "wincmd h", { noremap = true }) + vim.api.nvim_set_keymap("", "", "wincmd j", { noremap = true }) + vim.api.nvim_set_keymap("", "", "wincmd k", { noremap = true }) + vim.api.nvim_set_keymap("", "", "wincmd l", { noremap = true }) end ---}}} ---moving laterally when concealed {{{ -- https://stackoverflow.com/questions/12397103/the-conceal-feature-in-vim-still-makes-me-move-over-all-the-characters -- https://github.com/albfan/ag.vim/commit/bdccf94877401035377aafdcf45cd44b46a50fb5 - vim.cmd [[ + vim.cmd([[ function! s:ForwardSkipConceal(count) let cnt=a:count let mvcnt=0 @@ -1887,66 +1961,78 @@ _G.load_config = function() nnoremap l ForwardSkipConceal(v:count1) nnoremap h BackwardSkipConceal(v:count1) nnoremap hc ToggleConceal() - ]] + ]]) vim.opt.conceallevel = 0 - vim.opt.concealcursor = 'c' + vim.opt.concealcursor = "c" ---}}} ---copy/paste mode toggle and shortcuts {{{ -- vim.api.nvim_set_keymap('n', '', ':set invpaste paste?', {}) -- vim.api.nvim_set_keymap('i', '', ':set invpaste paste?', {}) - if vim.fn.has('mac') == 1 then - vim.api.nvim_set_keymap('', 'p', '"*p', {}) - vim.api.nvim_set_keymap('', 'y', '"*y', {}) - elseif vim.fn.has('unix') == 1 then - vim.api.nvim_set_keymap('', 'p', '"+p', {}) - vim.api.nvim_set_keymap('', 'y', '"+y', {}) + if vim.fn.has("mac") == 1 then + vim.api.nvim_set_keymap("", "p", '"*p', {}) + vim.api.nvim_set_keymap("", "y", '"*y', {}) + elseif vim.fn.has("unix") == 1 then + vim.api.nvim_set_keymap("", "p", '"+p', {}) + vim.api.nvim_set_keymap("", "y", '"+y', {}) end ---}}} ---line transposition {{{ - vim.api.nvim_set_keymap('n', '', ':set fdm=manual:m .+1:set fdm=marker', { noremap = true }) - vim.api.nvim_set_keymap('n', '', ':set fdm=manual:m .-2:set fdm=marker', { noremap = true }) - vim.api.nvim_set_keymap( 'v', '', ':set fdm=manual\':m \'>+1:set fdm=markergv', - { noremap = true }) - vim.api.nvim_set_keymap( 'v', '', ':set fdm=manual\':m \'<-2:set fdm=markergv', - { noremap = true }) + vim.api.nvim_set_keymap("n", "", ":set fdm=manual:m .+1:set fdm=marker", { noremap = true }) + vim.api.nvim_set_keymap("n", "", ":set fdm=manual:m .-2:set fdm=marker", { noremap = true }) + vim.api.nvim_set_keymap( + "v", + "", + ":set fdm=manual':m '>+1:set fdm=markergv", + { noremap = true } + ) + vim.api.nvim_set_keymap( + "v", + "", + ":set fdm=manual':m '<-2:set fdm=markergv", + { noremap = true } + ) ---}}} ---select last inserted text {{{ - vim.api.nvim_set_keymap('n', 'gV', '`[v`]', { noremap = true }) + vim.api.nvim_set_keymap("n", "gV", "`[v`]", { noremap = true }) ---}}} ---write with capital W{{{ - vim.cmd [[ + vim.cmd([[ command! W w - ]] + ]]) ---}}} ---delete trailling whitespace {{{ - vim.api.nvim_set_keymap('n', 'dt', ':execute "silent normal! mq" \':%s/\\s\\+$//ge\' "\\r`q"', - { silent = true }) + vim.api.nvim_set_keymap( + "n", + "dt", + ':execute "silent normal! mq" \':%s/\\s\\+$//ge\' "\\r`q"', + { silent = true } + ) ---}}} ---starts very magic regex {{{ - vim.api.nvim_set_keymap('n', '/', '/\\v', { noremap = true }) - vim.api.nvim_set_keymap('n', '?', '?\\v', { noremap = true }) + vim.api.nvim_set_keymap("n", "/", "/\\v", { noremap = true }) + vim.api.nvim_set_keymap("n", "?", "?\\v", { noremap = true }) ---}}} --- command-line window {{{ -- maps for the command-line window get on the way of quitting Vim - vim.api.nvim_set_keymap('n', 'q:', '', { nowait = true, noremap = true }) - vim.api.nvim_set_keymap('n', 'q/', '', { nowait = true, noremap = true }) - vim.api.nvim_set_keymap('n', 'q?', '', { nowait = true, noremap = true }) - vim.api.nvim_set_keymap('n', 'c:', 'q:', { noremap = true }) - vim.api.nvim_set_keymap('n', 'c/', 'q/', { noremap = true }) - vim.api.nvim_set_keymap('n', 'c?', 'q?', { noremap = true }) + vim.api.nvim_set_keymap("n", "q:", "", { nowait = true, noremap = true }) + vim.api.nvim_set_keymap("n", "q/", "", { nowait = true, noremap = true }) + vim.api.nvim_set_keymap("n", "q?", "", { nowait = true, noremap = true }) + vim.api.nvim_set_keymap("n", "c:", "q:", { noremap = true }) + vim.api.nvim_set_keymap("n", "c/", "q/", { noremap = true }) + vim.api.nvim_set_keymap("n", "c?", "q?", { noremap = true }) ---}}} ---}}} + --}}} ---cmd {{{ + --cmd {{{ --- reload a lua module {{{ function loaded(arglead, _, _) @@ -1973,15 +2059,15 @@ _G.load_config = function() print("Lua module", modname, "loaded.") end - vim.cmd [[ command! -nargs=1 -complete=customlist,v:lua.loaded Luareload lua reload() ]] + vim.cmd([[ command! -nargs=1 -complete=customlist,v:lua.loaded Luareload lua reload() ]]) ---}}} ---}}} + --}}} ---autocmd {{{ + --autocmd {{{ ---create directory if not exist {{{ - vim.cmd [[ + vim.cmd([[ augroup vimrc_directory autocmd! @@ -1997,17 +2083,17 @@ _G.load_config = function() endfunction autocmd BufWritePre * call s:auto_mkdir(expand(':p:h'), v:cmdbang) augroup END - ]] + ]]) ---}}} ---leave the command-line window {{{ - vim.api.nvim_create_autocmd('CmdwinEnter', { - command = [[nmap q :quit]] + vim.api.nvim_create_autocmd("CmdwinEnter", { + command = [[nmap q :quit]], }) ---}}} ---remove item from quickfix/loclist window {{{ - vim.cmd [[ + vim.cmd([[ augroup vimrc_quickfix autocmd! function! Remove_from_qf() @@ -2026,79 +2112,79 @@ _G.load_config = function() autocmd FileType qf nnoremap dd :call Remove_from_qf() autocmd FileType qf nnoremap q :cclose augroup END - ]] + ]]) ---}}} ---rc {{{ - vim.api.nvim_create_autocmd({'BufNewFile', 'BufRead'}, { - pattern = {"*.*rc", "*rc", "init.lua"}, - command = [[setlocal foldmethod=marker]] + vim.api.nvim_create_autocmd({ "BufNewFile", "BufRead" }, { + pattern = { "*.*rc", "*rc", "init.lua" }, + command = [[setlocal foldmethod=marker]], }) ---}}} ---direnv {{{ - vim.api.nvim_create_autocmd({'BufNewFile', 'BufRead'}, { - pattern = {".envrc"}, - command = [[set filetype=sh]] + vim.api.nvim_create_autocmd({ "BufNewFile", "BufRead" }, { + pattern = { ".envrc" }, + command = [[set filetype=sh]], }) ---}}} ---python {{{ - vim.api.nvim_create_autocmd('FileType', { - pattern = {"python"}, - command = [[setlocal vartabstop=4 varsofttabstop=4]] + vim.api.nvim_create_autocmd("FileType", { + pattern = { "python" }, + command = [[setlocal vartabstop=4 varsofttabstop=4]], }) ---}}} ---rmd {{{ - vim.api.nvim_create_autocmd('FileType', { - pattern = {"rmd"}, + vim.api.nvim_create_autocmd("FileType", { + pattern = { "rmd" }, command = [[ runtime ftplugin/markdown.vim runtime after/ftplugin/markdown.vim - ]] + ]], }) ---}}} ---julia {{{ - vim.api.nvim_create_autocmd({'BufNewFile', 'BufRead'}, { - pattern = {"*.jmd"}, - command = [[set filetype=markdown]] + vim.api.nvim_create_autocmd({ "BufNewFile", "BufRead" }, { + pattern = { "*.jmd" }, + command = [[set filetype=markdown]], }) ---}}} ---tex {{{ - vim.api.nvim_create_autocmd({'BufNewFile', 'BufRead'}, { - pattern = {"*.tex"}, - command = [[set filetype=tex]] + vim.api.nvim_create_autocmd({ "BufNewFile", "BufRead" }, { + pattern = { "*.tex" }, + command = [[set filetype=tex]], }) ---}}} ---asciidoctor {{{ - vim.api.nvim_create_autocmd('FileType', { - pattern = {"asciidoctor"}, + vim.api.nvim_create_autocmd("FileType", { + pattern = { "asciidoctor" }, command = [[ nnoremap ll :call ToggleAsciidoctorAutocompile() nnoremap ll :call ToggleAsciidoctorAutocompile() - ]] + ]], }) ---}}} ---elisp {{{ - vim.api.nvim_create_autocmd({'BufNewFile', 'BufRead'}, { - pattern = {"*.elisp"}, - command = [[set filetype=elisp]] + vim.api.nvim_create_autocmd({ "BufNewFile", "BufRead" }, { + pattern = { "*.elisp" }, + command = [[set filetype=elisp]], }) ---}}} ---hoon {{{ - vim.api.nvim_create_autocmd({'FileType'}, { - pattern = {"hoon"}, - callback = function() - vim.opt_local.commentstring = ":: %s" - vim.api.nvim_set_keymap('i', '', ' ', { noremap = true }) - end - -- command = [[setlocal commentstring=\:\:\ %s]] + vim.api.nvim_create_autocmd({ "FileType" }, { + pattern = { "hoon" }, + callback = function() + vim.opt_local.commentstring = ":: %s" + vim.api.nvim_set_keymap("i", "", " ", { noremap = true }) + end, + -- command = [[setlocal commentstring=\:\:\ %s]] }) ---}}} @@ -2137,71 +2223,68 @@ _G.load_config = function() end end end - end function set_org_indent() level, block = org_section_level() indent = level and level + 1 or level if block == "python" then - vim.opt_local.vartabstop = indent and indent .. ',4' or '4' - vim.opt_local.varsofttabstop = indent and indent .. ',4' or '4' + vim.opt_local.vartabstop = indent and indent .. ",4" or "4" + vim.opt_local.varsofttabstop = indent and indent .. ",4" or "4" else - vim.opt_local.vartabstop = indent and indent .. ',2' or '2' - vim.opt_local.varsofttabstop = indent and indent .. ',2' or '2' + vim.opt_local.vartabstop = indent and indent .. ",2" or "2" + vim.opt_local.varsofttabstop = indent and indent .. ",2" or "2" end end function unset_org_indent() - vim.opt_local.vartabstop = '2' - vim.opt_local.varsofttabstop = '2' + vim.opt_local.vartabstop = "2" + vim.opt_local.varsofttabstop = "2" end - vim.api.nvim_create_autocmd('FileType', { - pattern = {"org"}, - callback = function() - -- vim.keymap.set('n', '>>', function() - -- set_org_indent() - -- vim.cmd[[>]] - -- unset_org_indent() - -- end, { noremap = true, buffer = 0 }) - -- vim.keymap.set('n', '<<', function() - -- set_org_indent() - -- vim.cmd[[<]] - -- unset_org_indent() - -- end, { noremap = true, buffer = 0 }) - -- vim.keymap.set('v', '>', function() - -- set_org_indent() - -- vim.cmd[[:'<,'>>]] - -- unset_org_indent() - -- end, { noremap = true, buffer = 0 }) - vim.fn["shiftwidth"] = function() - local ok, ft = pcall(vim.api.nvim_get_option_value, "filetype", {}) - if (not ok) or (ft ~= "org") then - return vim.o.shiftwidth - end - level, block = org_section_level() - return level + vim.api.nvim_create_autocmd("FileType", { + pattern = { "org" }, + callback = function() + -- vim.keymap.set('n', '>>', function() + -- set_org_indent() + -- vim.cmd[[>]] + -- unset_org_indent() + -- end, { noremap = true, buffer = 0 }) + -- vim.keymap.set('n', '<<', function() + -- set_org_indent() + -- vim.cmd[[<]] + -- unset_org_indent() + -- end, { noremap = true, buffer = 0 }) + -- vim.keymap.set('v', '>', function() + -- set_org_indent() + -- vim.cmd[[:'<,'>>]] + -- unset_org_indent() + -- end, { noremap = true, buffer = 0 }) + vim.fn["shiftwidth"] = function() + local ok, ft = pcall(vim.api.nvim_get_option_value, "filetype", {}) + if (not ok) or (ft ~= "org") then + return vim.o.shiftwidth end - end, + level, block = org_section_level() + return level + end + end, }) - vim.api.nvim_create_autocmd('InsertEnter', { - pattern = {"*.org"}, - callback = set_org_indent + vim.api.nvim_create_autocmd("InsertEnter", { + pattern = { "*.org" }, + callback = set_org_indent, }) - vim.api.nvim_create_autocmd('InsertLeave', { - pattern = {"*.org"}, - callback = unset_org_indent + vim.api.nvim_create_autocmd("InsertLeave", { + pattern = { "*.org" }, + callback = unset_org_indent, }) ---}}} ----}}} - + ---}}} end -- }}} load_plugins() load_config() - diff --git a/nvim/lua/telescope_pickers/diagnostics.lua b/nvim/lua/telescope_pickers/diagnostics.lua new file mode 100644 index 0000000..efe94a8 --- /dev/null +++ b/nvim/lua/telescope_pickers/diagnostics.lua @@ -0,0 +1,294 @@ +-- Custom telescope picker for diagnostics +-- Modified from buil-in picker: https://github.com/nvim-telescope/telescope.nvim/blob/master/lua/telescope/builtin/__diagnostics.lua +local conf = require("telescope.config").values +local finders = require "telescope.finders" +local make_entry = require "telescope.make_entry" +local pickers = require "telescope.pickers" +local utils = require "telescope.utils" +local entry_display = require "telescope.pickers.entry_display" + +local diagnostics = {} + +local sorting_comparator = function(opts) + local current_buf = vim.api.nvim_get_current_buf() + local comparators = { + -- sort results by bufnr (prioritize cur buf), severity, lnum + buffer = function(a, b) + if a.bufnr == b.bufnr then + if a.type == b.type then + return a.lnum < b.lnum + else + return a.type < b.type + end + else + if a.bufnr == current_buf then + return true + end + if b.bufnr == current_buf then + return false + end + return a.bufnr < b.bufnr + end + end, + severity = function(a, b) + if a.type < b.type then + return true + elseif a.type > b.type then + return false + end + + if a.bufnr == b.bufnr then + return a.lnum < b.lnum + elseif a.bufnr == current_buf then + return true + elseif b.bufnr == current_buf then + return false + else + return a.bufnr < b.bufnr + end + end, + } + + local sort_by = vim.F.if_nil(opts.sort_by, "buffer") + return comparators[sort_by] +end + +local convert_diagnostic_type = function(severities, severity) + -- convert from string to int + if type(severity) == "string" then + -- make sure that e.g. error is uppercased to ERROR + return severities[severity:upper()] + end + -- otherwise keep original value, incl. nil + return severity +end + +local diagnostics_to_tbl = function(opts) + opts = vim.F.if_nil(opts, {}) + local items = {} + local severities = vim.diagnostic.severity + + opts.severity = convert_diagnostic_type(severities, opts.severity) + opts.severity_limit = convert_diagnostic_type(severities, opts.severity_limit) + opts.severity_bound = convert_diagnostic_type(severities, opts.severity_bound) + + local diagnosis_opts = { severity = {}, namespace = opts.namespace } + if opts.severity ~= nil then + if opts.severity_limit ~= nil or opts.severity_bound ~= nil then + utils.notify("builtin.diagnostics", { + msg = "Invalid severity parameters. Both a specific severity and a limit/bound is not allowed", + level = "ERROR", + }) + return {} + end + diagnosis_opts.severity = opts.severity + else + if opts.severity_limit ~= nil then + diagnosis_opts.severity["min"] = opts.severity_limit + end + if opts.severity_bound ~= nil then + diagnosis_opts.severity["max"] = opts.severity_bound + end + if vim.version().minor > 9 and vim.tbl_isempty(diagnosis_opts.severity) then + diagnosis_opts.severity = nil + end + end + + opts.root_dir = opts.root_dir == true and vim.loop.cwd() or opts.root_dir + + local bufnr_name_map = {} + local filter_diag = function(diagnostic) + if bufnr_name_map[diagnostic.bufnr] == nil then + bufnr_name_map[diagnostic.bufnr] = vim.api.nvim_buf_get_name(diagnostic.bufnr) + end + + local root_dir_test = not opts.root_dir + or string.sub(bufnr_name_map[diagnostic.bufnr], 1, #opts.root_dir) == opts.root_dir + local listed_test = not opts.no_unlisted or vim.api.nvim_buf_get_option(diagnostic.bufnr, "buflisted") + + return root_dir_test and listed_test + end + + local preprocess_diag = function(diagnostic) + local text = "" + if diagnostic.code ~= nil then + code_text = ("[%s]"):format(vim.trim(diagnostic.code:gsub("[\n]", ""))) + else + code_text = "" + end + if diagnostic.source ~= nil then + diagnostic_text = ("(%s)"):format(vim.trim(diagnostic.source:gsub("[\n]", ""))) + else + diagnostic_text = "" + end + text = ("%s %s %s"):format(code_text, vim.trim(diagnostic.message:gsub("[\n]", "")), diagnostic_text) + return { + bufnr = diagnostic.bufnr, + filename = bufnr_name_map[diagnostic.bufnr], + lnum = diagnostic.lnum + 1, + col = diagnostic.col + 1, + text = text, + type = severities[diagnostic.severity] or severities[1], + } + end + + for _, d in ipairs(vim.diagnostic.get(opts.bufnr, diagnosis_opts)) do + if filter_diag(d) then + table.insert(items, preprocess_diag(d)) + end + end + + table.sort(items, sorting_comparator(opts)) + + return items +end + +function gen_from_diagnostics(opts) + opts = opts or {} + + local type_diagnostic = vim.diagnostic.severity + local signs = (function() + if opts.no_sign then + return + end + local signs = {} + for _, severity in ipairs(type_diagnostic) do + local status, sign = pcall(function() + -- only the first char is upper all others are lowercalse + return vim.trim(vim.fn.sign_getdefined("DiagnosticSign" .. severity:lower():gsub("^%l", string.upper))[1].text) + end) + if not status then + sign = severity:sub(1, 1) + end + signs[severity] = sign + end + return signs + end)() + + local sign_width + if opts.disable_coordinates then + sign_width = signs ~= nil and 2 or 0 + else + sign_width = signs ~= nil and 10 or 8 + end + + local display_items = { + { width = sign_width }, + { remaining = true }, + } + local line_width = vim.F.if_nil(opts.line_width, 0.5) + local line_width_opts = { width = line_width } + if type(line_width) == "string" and line_width == "full" then + line_width_opts = {} + end + local hidden = utils.is_path_hidden(opts) + if not hidden then + table.insert(display_items, 2, line_width_opts) + end + local displayer = entry_display.create { + separator = "▏", + items = display_items, + } + + local make_display = function(entry) + local display_path, path_style = utils.transform_path(opts, entry.filename) + + -- add styling of entries + local pos = string.format("%4d:%2d", entry.lnum, entry.col) + local line_info_text = signs and signs[entry.type] .. " " or "" + local line_info = { + opts.disable_coordinates and line_info_text or line_info_text .. pos, + "DiagnosticSign" .. entry.type, + } + + return displayer { + line_info, + entry.text, + { + display_path, + function() + return path_style + end, + }, + } + end + + local errlist_type_map = { + [type_diagnostic.ERROR] = "E", + [type_diagnostic.WARN] = "W", + [type_diagnostic.INFO] = "I", + [type_diagnostic.HINT] = "N", + } + + return function(entry) + return make_entry.set_default_entry_mt({ + value = entry, + ordinal = ("%s %s"):format(not hidden and entry.filename or "", entry.text), + display = make_display, + filename = entry.filename, + type = entry.type, + lnum = entry.lnum, + col = entry.col, + text = entry.text, + qf_type = errlist_type_map[type_diagnostic[entry.type]], + }, opts) + end +end + +diagnostics.get = function(opts) + if opts.bufnr ~= 0 then + opts.bufnr = nil + end + if type(opts.bufnr) == "string" then + opts.bufnr = tonumber(opts.bufnr) + end + if opts.bufnr ~= nil then + opts.path_display = vim.F.if_nil(opts.path_display, "hidden") + end + + local locations = diagnostics_to_tbl(opts) + + if vim.tbl_isempty(locations) then + utils.notify("builtin.diagnostics", { + msg = "No diagnostics found", + level = "INFO", + }) + return + end + + if type(opts.line_width) == "string" and opts.line_width ~= "full" then + utils.notify("builtin.diagnostics", { + msg = string.format("'%s' is not a valid value for line_width", opts.line_width), + level = "ERROR", + }) + return + end + + pickers + .new(opts, { + prompt_title = opts.bufnr == nil and "Workspace Diagnostics" or "Document Diagnostics", + finder = finders.new_table { + results = locations, + entry_maker = gen_from_diagnostics(opts), + }, + previewer = conf.qflist_previewer(opts), + sorter = conf.prefilter_sorter { + tag = "type", + sorter = conf.generic_sorter(opts), + }, + }) + :find() +end + +local function apply_checks(mod) + for k, v in pairs(mod) do + mod[k] = function(opts) + opts = opts or {} + v(opts) + end + end + + return mod +end + +return apply_checks(diagnostics) diff --git a/nvim/lua/telescope_pickers/init.lua b/nvim/lua/telescope_pickers/init.lua new file mode 100644 index 0000000..ba9f051 --- /dev/null +++ b/nvim/lua/telescope_pickers/init.lua @@ -0,0 +1,93 @@ +-- Custom telescope pickers +-- Modified from buil-in picker: https://github.com/nvim-telescope/telescope.nvim/blob/master/lua/telescope/builtin/init.lua +local pickers = {} + +-- Ref: https://github.com/tjdevries/lazy.nvim +local function require_on_exported_call(mod) + return setmetatable({}, { + __index = function(_, picker) + return function(...) + return require(mod)[picker](...) + end + end, + }) +end + +--- Lists diagnostics +--- - Fields: +--- - `All severity flags can be passed as `string` or `number` as per `:vim.diagnostic.severity:` +--- - Default keymaps: +--- - ``: show autocompletion menu to prefilter your query with the diagnostic you want to see (i.e. `:warning:`) +--- - sort_by option: +--- - "buffer": order by bufnr (prioritizing current bufnr), severity, lnum +--- - "severity": order by severity, bufnr (prioritizing current bufnr), lnum +---@param opts table: options to pass to the picker +---@field bufnr number|nil: Buffer number to get diagnostics from. Use 0 for current buffer or nil for all buffers +---@field severity string|number: filter diagnostics by severity name (string) or id (number) +---@field severity_limit string|number: keep diagnostics equal or more severe wrt severity name (string) or id (number) +---@field severity_bound string|number: keep diagnostics equal or less severe wrt severity name (string) or id (number) +---@field root_dir string|boolean: if set to string, get diagnostics only for buffers under this dir otherwise cwd +---@field no_unlisted boolean: if true, get diagnostics only for listed buffers +---@field no_sign boolean: hide DiagnosticSigns from Results (default: false) +---@field line_width string|number: set length of diagnostic entry text in Results. Use 'full' for full untruncated text +---@field namespace number: limit your diagnostics to a specific namespace +---@field disable_coordinates boolean: don't show the line & row numbers (default: false) +---@field sort_by string: sort order of the diagnostics results; see above notes (default: "buffer") +-- pickers.diagnostics = require_on_exported_call("diagnostics").get +-- local diagnostics = require"telescope_pickers.diagnostics" +-- pickers.diagnostics = diagnostics.get +pickers.diagnostics = require_on_exported_call("telescope_pickers.diagnostics").get + +local apply_config = function(mod) + for k, v in pairs(mod) do + mod[k] = function(opts) + local pickers_conf = require("telescope.config").pickers + + opts = opts or {} + opts.bufnr = opts.bufnr or vim.api.nvim_get_current_buf() + opts.winnr = opts.winnr or vim.api.nvim_get_current_win() + local pconf = pickers_conf[k] or {} + local defaults = (function() + if pconf.theme then + return require("telescope.themes")["get_" .. pconf.theme](pconf) + end + return vim.deepcopy(pconf) + end)() + + if pconf.mappings then + defaults.attach_mappings = function(_, map) + for mode, tbl in pairs(pconf.mappings) do + for key, action in pairs(tbl) do + map(mode, key, action) + end + end + return true + end + end + + if pconf.attach_mappings and opts.attach_mappings then + local opts_attach = opts.attach_mappings + opts.attach_mappings = function(prompt_bufnr, map) + pconf.attach_mappings(prompt_bufnr, map) + return opts_attach(prompt_bufnr, map) + end + end + + if defaults.attach_mappings and opts.attach_mappings then + local opts_attach = opts.attach_mappings + opts.attach_mappings = function(prompt_bufnr, map) + defaults.attach_mappings(prompt_bufnr, map) + return opts_attach(prompt_bufnr, map) + end + end + + v(vim.tbl_extend("force", defaults, opts)) + end + end + + return mod +end + +pickers = apply_config(pickers) + +return pickers diff --git a/nvim/queries/yaml/highlights.scm b/nvim/queries/yaml/highlights.scm new file mode 100644 index 0000000..cf88921 --- /dev/null +++ b/nvim/queries/yaml/highlights.scm @@ -0,0 +1,9 @@ +;; inherits: yaml +;; extends +(double_quote_scalar) @spell + +(single_quote_scalar) @spell + +(block_scalar) @spell + +(string_scalar) @spell diff --git a/shells/bashrc b/shells/bashrc index 1fc9da5..808683d 100644 --- a/shells/bashrc +++ b/shells/bashrc @@ -3,6 +3,16 @@ if [[ $- == *i* ]]; then # Determine OS type {{{ export OSTYPE="$(uname -s)" + if [[ "$OSTYPE" = Darwin* ]]; then + # macOS's $HOST changes with dhcp, etc. Use ComputerName if possible. + SHORT_HOST=$(scutil --get ComputerName 2>/dev/null) || SHORT_HOST="${HOSTNAME/.*/}" + else + # https://superuser.com/questions/1749781/how-can-i-check-if-the-environment-is-wsl-from-a-shell-script + if [ -f /proc/sys/fs/binfmt_misc/WSLInterop ]; then + export OSTYPE="Wsl" + fi + SHORT_HOST="${HOSTNAME/.*/}" + fi # }}} # History {{{ @@ -15,30 +25,9 @@ if [[ $- == *i* ]]; then # }}} # Theme {{{ - # https://gist.github.com/thomd/7667642 - # https://geoff.greer.fm/lscolors/ - function get_termbg() { - if [[ "$TERM" == "xterm-"* ]] || [[ "$TERM" == "alacritty" ]]; then - oldstty=$(stty -g) - stty raw -echo min 0 time 1 - # terminal escape sequence to get the terminal background color - # only works in xterms - # https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands - printf '\033]11;?\033\\' - sleep 0.00000001 - read -r termbg - stty $oldstty - local termbg=$(echo $termbg | sed 's/.*\(rgb:[0-9a-f/]*\).*/\1/') - if [[ $termbg == "rgb:f8f8/fbfb/f8f8" ]]; then - export THEME="leuven" - elif [[ $termbg == "rgb:2828/2a2a/3636" ]]; then - export THEME="dracula" - fi - fi - } - if [[ -z "$THEME" ]]; then export THEME=""; fi - get_termbg + if [[ -z "$THEME" ]]; then export THEME="leuven"; fi export CLICOLOR=1 + # https://geoff.greer.fm/lscolors/ export LSCOLORS="excxhxDxbxhxhxhxhxfxfx" export LS_COLORS="" if [[ $THEME == "leuven" ]]; then @@ -274,7 +263,7 @@ if [[ $- == *i* ]]; then alias ls='ls --color=auto' ## }}} - if [[ $OSTYPE == Linux* ]]; then + if [[ "$OSTYPE" = Linux* ]]; then ## More convenient xdg-open {{{ function open { setsid xdg-open "$1" &>/dev/null; } @@ -282,7 +271,7 @@ if [[ $- == *i* ]]; then fi - if [[ $OSTYPE == Darwin* ]]; then + if [[ "$OSTYPE" = Darwin* ]]; then ## turn on/off hidden files visibility {{{ alias showFiles='defaults write com.apple.finder AppleShowAllFiles YES; killall Finder /System/Library/CoreServices/Finder.app' @@ -299,6 +288,20 @@ if [[ $- == *i* ]]; then fi + if [[ "$OSTYPE" = Wsl* ]]; then + + ## More convenient explorer.exe {{{ + function open { + win_path=$(wslpath -w "$1") + explorer.exe "$win_path" &>/dev/null + (( $? > 1 )) && return 1 || return 0 + } + + export WINHOME=$(wslpath -u $(cmd.exe /c "echo %USERPROFILE%" 2>&1 | tail -n 1 | tr -d '\r')) + ## }}} + + fi + # }}} # PATH {{{ diff --git a/shells/zshenv b/shells/zshenv new file mode 100644 index 0000000..d7d28b0 --- /dev/null +++ b/shells/zshenv @@ -0,0 +1,10 @@ +## wsl {{{ +# https://superuser.com/questions/1749781/how-can-i-check-if-the-environment-is-wsl-from-a-shell-script +if [ -f /proc/sys/fs/binfmt_misc/WSLInterop ]; then + # alias for .exe utilities + if hash wezterm.exe 2>/dev/null; then + alias wezterm=wezterm.exe + fi +fi +## }}} + diff --git a/shells/zshrc b/shells/zshrc index 4c7060b..6326742 100644 --- a/shells/zshrc +++ b/shells/zshrc @@ -1,8 +1,18 @@ # Avoid breaking non-interactive logins (eg sftp) if [[ $- == *i* ]]; then - # Determine OS type {{{ + # Environment variables {{{ export OSTYPE="$(uname -s)" + if [[ "$OSTYPE" = Darwin* ]]; then + # macOS's $HOST changes with dhcp, etc. Use ComputerName if possible. + SHORT_HOST=$(scutil --get ComputerName 2>/dev/null) || SHORT_HOST="${HOST/.*/}" + else + # https://superuser.com/questions/1749781/how-can-i-check-if-the-environment-is-wsl-from-a-shell-script + if [ -f /proc/sys/fs/binfmt_misc/WSLInterop ]; then + export OSTYPE="Wsl" + fi + SHORT_HOST="${HOST/.*/}" + fi # }}} # Shell options {{{ @@ -29,12 +39,11 @@ if [[ $- == *i* ]]; then # }}} # Theme {{{ - # https://gist.github.com/thomd/7667642 - # https://geoff.greer.fm/lscolors/ - if [[ -z "$THEME" ]]; then export THEME=""; fi + if [[ -z "$THEME" ]]; then export THEME="leuven"; fi export CLICOLOR=1 + # https://geoff.greer.fm/lscolors/ export LSCOLORS="excxhxDxbxhxhxhxhxfxfx" - export LS_COLORS="" + export LS_COLORS="leuven" if [[ $THEME == "leuven" ]]; then LS_COLORS="no=00:fi=00:di=34:ln=32;102:so=30;107:pi=33;103:ex=31:cd=33;107:bd=33;107:su=31;101:sg=34;106:tw=35;101:ow=34;101" elif [[ $THEME == "dracula" ]]; then @@ -134,10 +143,17 @@ if [[ $- == *i* ]]; then ## pyenv {{{ if hash pyenv 2>/dev/null; then export PYENV_ROOT="$(pyenv root)" + elif [ -d "$HOME/.pyenv" ]; then + export PYENV_ROOT="$HOME/.pyenv" + export PATH="$PYENV_ROOT/bin:$PATH" + fi + if hash pyenv 2>/dev/null; then eval "$(pyenv init --path)" eval "$(pyenv init -)" eval "$(pyenv virtualenv-init -)" - alias brew='env PATH="${PATH//$(pyenv root)\/shims:/}" brew' + if hash brew 2>/dev/null; then + alias brew='env PATH="${PATH//$(pyenv root)\/shims:/}" brew' + fi fi ## }}} @@ -157,7 +173,7 @@ if [[ $- == *i* ]]; then alias emacs="TERM=xterm-emacs emacs -nw" fi fi - ##}}} + ## }}} ## nnn {{{ # https://github.com/jarun/nnn @@ -182,7 +198,80 @@ if [[ $- == *i* ]]; then fi } fi - ##}}} + ## }}} + + ## ssh {{{ + # see: https://rabexc.org/posts/pitfalls-of-ssh-agents + # see: https://github.com/ohmyzsh/ohmyzsh/blob/master/plugins/ssh-agent/ssh-agent.plugin.zsh + ssh_env_cache="$HOME/.ssh/environment-$SHORT_HOST" + + function _start_agent() { + # Do not start ssh agent in remote ssh session + if [[ -n "$SSH_CONNECTION" ]]; then + return 0 + fi + + # Check if ssh-agent is already running + if [[ -f "$ssh_env_cache" ]]; then + . "$ssh_env_cache" > /dev/null + + # Test if $SSH_AUTH_SOCK is visible + zmodload zsh/net/socket + if [[ -S "$SSH_AUTH_SOCK" ]] && zsocket "$SSH_AUTH_SOCK" 2>/dev/null; then + return 0 + fi + fi + + if [[ ! -d "$HOME/.ssh" ]]; then + echo "ssh-agent requires ~/.ssh directory" + return 1 + fi + + # start ssh-agent and setup environment + ssh-agent -s -t 8h | sed '/^echo/d' >! "$ssh_env_cache" + chmod 600 "$ssh_env_cache" + . "$ssh_env_cache" > /dev/null + } + + _start_agent + + # adapted from ChatGPT + _ssh_add_identities() { + + # variables managed by _arguments + local curcontext="$curcontext" state line + # declares an associative array which can be used to store and retrieve options and their values + typeset -A opt_args + + local identities + + # gather identities from .pub files, stripping the .pub extension + identities=($( + ls -1 $HOME/.ssh/*.pub 2>/dev/null | sed 's/\.pub$//' + )) + + # zsh builtin for parsing and handling CLI arguments within completion functions + # -C option specifies that the completion should handle arguments starting + # with anything (`*`), with the last argument being an identity + # (`::identity`) which is directed to the `identity` state for further completion + _arguments -C '*::ssh_identity:->ssh_identity' && return + + case $state in + ssh_identity) + if (( ${#identities[@]} )); then + _describe -t identities 'SSH identities' identities && return + fi + _files + ;; + esac + } + + compdef _ssh_add_identities ssh-add + autoload -Uz _ssh_add_identities + + unset ssh_env_cache + unfunction _start_agent + ## }}} # }}} @@ -225,26 +314,6 @@ if [[ $- == *i* ]]; then # https://github.com/zsh-users/zsh/blob/master/Misc/vcs_info-examples#L51 precmd_ps1() { - if [[ "$TERM" == "xterm-"* ]] || [[ "$TERM" == "alacritty" ]]; then - # https://gist.github.com/blueyed/c8470c2aad3381c33ea3 - # https://stackoverflow.com/questions/2507337/how-to-determine-a-terminals-background-color - local oldstty=$(stty -g) - stty raw -echo min 0 time 1 - # terminal escape sequence to get the terminal background color - # only works in xterms - # https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands - printf '\033]11;?\033\\' - sleep 0.00000001 - read -r termbg - stty $oldstty - local termbg=$(echo $termbg | sed 's/.*\(rgb:[0-9a-f/]*\).*/\1/') - if [[ $termbg == "rgb:f8f8/fbfb/f8f8" ]]; then - THEME="leuven" - elif [[ $termbg == "rgb:2828/2a2a/3636" ]]; then - THEME="dracula" - fi - fi - # https://zsh.sourceforge.io/Doc/Release/Prompt-Expansion.html#Visual-effects color="" if [[ $THEME == "leuven" ]]; then @@ -339,7 +408,7 @@ if [[ $- == *i* ]]; then function = { echo "$@" | bc -l } ## }}} - if [[ $OSTYPE == Linux* ]]; then + if [[ "$OSTYPE" = Linux* ]]; then ## More convenient xdg-open {{{ function open { setsid xdg-open "$1" &>/dev/null } @@ -347,7 +416,7 @@ if [[ $- == *i* ]]; then fi - if [[ $OSTYPE == Darwin* ]]; then + if [[ "$OSTYPE" = Darwin* ]]; then ## turn on/off hidden files visibility {{{ alias showFiles='defaults write com.apple.finder AppleShowAllFiles YES; killall Finder /System/Library/CoreServices/Finder.app' @@ -364,6 +433,56 @@ if [[ $- == *i* ]]; then fi + if [[ "$OSTYPE" = Wsl* ]]; then + + ## More convenient explorer.exe {{{ + function open { + win_path=$(wslpath -w "$1") + explorer.exe "$win_path" &>/dev/null + (( $? > 1 )) && return 1 || return 0 + } + + export WINHOME=$(wslpath -u $(cmd.exe /c "echo %USERPROFILE%" 2>&1 | tail -n 1 | tr -d '\r')) + ## }}} + + ## More robust terminal image + if [ "$TERM_PROGRAM" = "WezTerm" ]; then + if hash timg 2>/dev/null; then + function timgcat() { + if [ $# -eq 0 ]; then + echo "No argument provided. Exiting ..." + exit 1 + fi + + timg -p i "$@" + + printf "\rPress 'q' to exit." + + # Save current terminal settings + old_stty_cfg=$(stty -g) + + # Ensure terminal settings are restored on exit + trap 'stty "$old_stty_cfg"' EXIT + + # Set terminal to raw mode + stty raw -echo + + while : ; do + key=$(dd bs=1 count=1 2>/dev/null) + if [ "$key" = 'q' ]; then + break + fi + done + stty "$old_stty_cfg" + printf "\n\033[2K\r" + } + if hash nnn 2>/dev/null; then + export NNN_PREVIEWIMGPROG="timg -p i" + fi + fi + fi + + fi # }}} # PATH {{{