Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Argument color doesn't reset for values in multi-column layout #414

Closed
mjcarman opened this issue Jan 30, 2023 · 11 comments
Closed

Argument color doesn't reset for values in multi-column layout #414

mjcarman opened this issue Jan 30, 2023 · 11 comments
Labels
bug Something isn't working

Comments

@mjcarman
Copy link

When there are only a few possible completions and clink displays them all in a single column, colors are set/reset correctly.

arginfo-single

But when there are many possible completions and clink switches to a multi-column layout, the flag/arg color isn't reset after an argument info hint (unless the arg/flag is selected). The remainder of the line is rendered as color.arginfo.

arginfo-multi

@chrisant996 chrisant996 added the bug Something isn't working label Jan 30, 2023
@chrisant996
Copy link
Owner

chrisant996 commented Jan 30, 2023

@mjcarman Thanks for reporting this.

I'm not able to reproduce it, so there is probably something additional involved:

image

Can you share your clink set output, and also the Lua code for the argmatcher for rg?

(Also, what version of Clink is in use?)

@chrisant996
Copy link
Owner

@mjcarman Found it. My .inputrc file has set colored-stats on. By default that's off. The "Use enhanced defaults" installation setting also changes the default to on.

When colored-stats is off, the color was not reset.

@mjcarman
Copy link
Author

@chrisant996 You said you found the issue, but for tracking and reproduction purposes I'm running clink 1.4.14. colored-stats isn't set for me, though I could swear I did a "use enhanced defaults" installation. Output of clink set:

autosuggest.async                 True
autosuggest.enable                True
autosuggest.original_case         True
autosuggest.strategy              match_prev_cmd history completion
clink.autostart                   
clink.autoupdate                  True
clink.colorize_input              True
clink.default_bindings            windows
clink.logo                        full
clink.max_input_rows              0
clink.paste_crlf                  crlf
clink.path                        
clink.promptfilter                True
clink.update_interval             5
cmd.admin_title_prefix            
cmd.altf4_exits                   True
cmd.auto_answer                   off
cmd.ctrld_exits                   False
cmd.get_errorlevel                True
color.arg                         bold
color.arginfo                     sgr 38;5;172
color.argmatcher                  sgr 1;38;5;40
color.cmd                         sgr 1;38;5;231
color.cmdredir                    sgr 38;5;172
color.cmdsep                      sgr 38;5;214
color.comment_row                 sgr 38;5;87;48;5;18
color.description                 sgr 38;5;39
color.doskey                      sgr 1;38;5;75
color.executable                  sgr 1;38;5;33
color.filtered                    sgr 38;5;231
color.flag                        sgr 38;5;117
color.git.star                    bright green
color.hidden                      sgr 38;5;160
color.histexpand                  sgr 97;48;5;55
color.horizscroll                 sgr 38;5;16;48;5;30
color.input                       sgr 38;5;222
color.interact                    bold
color.message                     default
color.modmark                     
color.popup                       
color.popup_desc                  
color.prompt                      
color.readonly                    sgr 38;5;28
color.selected_completion         sgr 38;5;16;48;5;254
color.selection                   sgr 38;5;16;48;5;179
color.suggestion                  sgr 38;5;239
color.unexpected                  default
color.unrecognized                sgr 38;5;203
color.yarn.module                 bright green
color.yarn.script                 bright blue
debug.log_terminal                False
directories.dupe_mode             add
doskey.enhanced                   True
exec.aliases                      True
exec.commands                     True
exec.cwd                          True
exec.dirs                         True
exec.enable                       True
exec.files                        False
exec.path                         True
exec.space_prefix                 True
files.hidden                      True
files.system                      False
history.auto_expand               True
history.dont_add_to_history_cmds  exit history
history.dupe_mode                 erase_prev
history.expand_mode               not_quoted
history.ignore_space              True
history.max_lines                 25000
history.save                      True
history.shared                    False
history.sticky_search             False
history.time_format               %F %T  
history.time_stamp                show
lua.break_on_error                False
lua.break_on_traceback            False
lua.debug                         False
lua.path                          
lua.reload_scripts                False
lua.strict                        True
lua.traceback_on_error            False
match.expand_abbrev               True
match.expand_envvars              True
match.fit_columns                 True
match.ignore_accent               True
match.ignore_case                 relaxed
match.max_fitted_matches          0
match.max_rows                    0
match.preview_rows                0
match.sort_dirs                   before
match.substring                   True
match.translate_slashes           system
match.wild                        True
prompt.async                      True
prompt.transient                  off
readline.hide_stderr              False
terminal.adjust_cursor_style      True
terminal.color_emoji              auto
terminal.differentiate_keys       False
terminal.east_asian_ambiguous     auto
terminal.emulation                auto
terminal.mouse_input              auto
terminal.mouse_modifier           
terminal.raw_esc                  False
terminal.use_altgr_substitute     False

My argmatcher for rg is

-- argument completion for ripgrep v13.0
require("arghelper")

local file_matches       = clink.argmatcher():addarg(clink.filematches)
local num_matches        = clink.argmatcher():addarg()
local color_spec_matches = clink.argmatcher():addarg({fromhistory=true})
local encoding_matches   = clink.argmatcher():addarg({fromhistory=true})
local separator_matches  = clink.argmatcher():addarg({fromhistory=true})
local glob_matches       = clink.argmatcher():addarg({fromhistory=true})
local pattern_matches    = clink.argmatcher():addarg({fromhistory=true})
local replace_matches    = clink.argmatcher():addarg({fromhistory=true})
local type_matches       = clink.argmatcher():addarg({fromhistory=true})
local type_spec_matches  = clink.argmatcher():addarg({fromhistory=true})
local engine_parser      = clink.argmatcher():addarg({"default", "pcre2", "auto"})
local when_parser        = clink.argmatcher():addarg({"never", "auto", "always", "ansi"})
local sort_parser        = clink.argmatcher()
  :_addexarg({
      { "none",     "(Default) Do not sort results. Fastest. Can be multi-threaded."    },
      { "path",     "Sort by file path. Always single-threaded."                        },
      { "modified", "Sort by the last modified time on a file. Always single-threaded." },
      { "accessed", "Sort by the last accessed time on a file. Always single-threaded." },
      { "created",  "Sort by the creation time on a file. Always single-threaded."      },
  })


clink.argmatcher("rg")
:_addexflags({
    { "-A", hide=true }, { "--after-context"           .. num_matches,        " <NUM>",              "Show NUM lines after each match."                         },
    { "-B", hide=true }, { "--before-context"          .. num_matches,        " <NUM>",              "Show NUM lines before each match."                        },
                         { "--color"                   .. when_parser,        " <WHEN>",             "Controls when to use color."                              },
                         { "--colors"                  .. color_spec_matches, " <COLOR_SPEC>",       "Configure color settings and styles."                     },
    { "-C", hide=true }, { "--context"                 .. num_matches,        " <NUM>",              "Show NUM lines before and after each match."              },
                         { "--context-separator"       .. separator_matches,  " <SEPARATOR>",        "Set the context separator string."                        },
                         { "--dfa-size-limit"          .. num_matches,        " <NUM+SUFFIX>",       "The upper size limit of the regex DFA."                   },
    { "-E", hide=true }, { "--encoding"                .. encoding_matches,   " <ENCODING>",         "Specify the text encoding of files to search."            },
                         { "--engine"                  .. engine_parser,      " <ENGINE>",           "Specify which regexp engine to use."                      },
                         { "--field-context-separator" .. separator_matches,  " <SEPARATOR>",        "Set the field context separator."                         },
                         { "--field-match-separator"   .. separator_matches,  " <SEPARATOR>",        "Set the match separator."                                 },
    { "-f", hide=true }, { "--file"                    .. file_matches,       " <PATTERNFILE>",      "Search for patterns from the given file."                 },
    { "-g", hide=true }, { "--glob"                    .. glob_matches,       " <GLOB>",             "Include or exclude files."                                },
                         { "--iglob",                                                                "Include or exclude files case insensitively."             },
                         { "--ignore-file"             .. file_matches,       " <PATH>",             "Specify additional ignore files."                         },
    { "-M", hide=true }, { "--max-columns"             .. num_matches,        " <NUM>",              "Don't print lines longer than this limit."                },
    { "-m", hide=true }, { "--max-count"               .. num_matches,        " <NUM>",              "Limit the number of matches."                             },
                         { "--max-depth"               .. num_matches,        " <NUM>",              "Descend at most NUM directories."                         },
                         { "--max-filesize"            .. num_matches,        " <NUM+SUFFIX>",       "Ignore files larger than NUM in size."                    },
                         { "--path-separator"          .. separator_matches,  " <SEPARATOR>",        "Set the path separator."                                  },
                         { "--pre"                     .. file_matches,       " <COMMAND>",          "search outputs of COMMAND FILE for each FILE"             },
                         { "--pre-glob"                .. glob_matches,       " <GLOB>",             "Include or exclude files from a preprocessing command."   },
                         { "--regex-size-limit"        .. num_matches,        " <NUM+SUFFIX>",       "The upper size limit of the compiled regex."              },
    { "-e", hide=true }, { "--regexp"                  .. pattern_matches,    " <PATTERN>",          "A pattern to search for."                                 },
    { "-r", hide=true }, { "--replace"                 .. replace_matches,    " <REPLACEMENT_TEXT>", "Replace matches with the given text."                     },
                         { "--sort"                    .. sort_parser,        " <SORTBY>",           "Sort results in ascending order. Implies --threads=1."    },
                         { "--sortr"                   .. sort_parser,        " <SORTBY>",           "Sort results in descending order. Implies --threads=1."   },
    { "-j", hide=true }, { "--threads"                 .. num_matches,        " <NUM>",              "The approximate number of threads to use."                },
    { "-t", hide=true }, { "--type"                    .. type_matches,       " <TYPE>",             "Only search files matching TYPE."                         },
                         { "--type-add"                .. type_spec_matches,  " <TYPE_SPEC>",        "Add a new glob for a file type."                          },
                         { "--type-clear"              .. type_matches,       " <TYPE>",             "Clear globs for a file type."                             },
    { "-T", hide=true }, { "--type-not"                .. type_matches,       " <TYPE>",             "Do not search files matching TYPE."                       },
                         { "--auto-hybrid-regex",                                                    "Dynamically use PCRE2 if necessary."                      },
                         { "--no-auto-hybrid-regex",                                                 "no-auto-hybrid-regex"                                     },
                         { "--binary",                                                               "Search binary files."                                     },
                         { "--no-binary",                                                            "no-binary"                                                },
                         { "--block-buffered",                                                       "Force block buffering."                                   },
                         { "--no-block-buffered",                                                    "no-block-buffered"                                        },
    { "-b", hide=true }, { "--byte-offset",                                                          "Print the 0-based byte offset for each matching line."    },
    { "-s", hide=true }, { "--case-sensitive",                                                       "Search case sensitively (default },."                     },
                         { "--column",                                                               "Show column numbers."                                     },
                         { "--no-column",                                                            "no-column"                                                },
                         { "--no-context-separator",                                                 "no-context-separator"                                     },
    { "-c", hide=true }, { "--count",                                                                "Only show the count of matching lines for each file."     },
                         { "--count-matches",                                                        "Only show the count of individual matches for each file." },
                         { "--crlf",                                                                 "Support CRLF line terminators (useful on Windows)."       },
                         { "--no-crlf",                                                              "no-crlf"                                                  },
                         { "--debug",                                                                "Show debug messages."                                     },
                         { "--trace",                                                                "trace"                                                    },
                         { "--no-encoding",                                                          "no-encoding"                                              },
                         { "--files",                                                                "Print each file that would be searched."                  },
    { "-l", hide=true }, { "--files-with-matches",                                                   "Print the paths with at least one match."                 },
                         { "--files-without-match",                                                  "Print the paths that contain zero matches."               },
    { "-F", hide=true }, { "--fixed-strings",                                                        "Treat the pattern as a literal string."                   },
                         { "--no-fixed-strings",                                                     "no-fixed-strings"                                         },
    { "-L", hide=true }, { "--follow",                                                               "Follow symbolic links."                                   },
                         { "--no-follow",                                                            "no-follow"                                                },
                         { "--glob-case-insensitive",                                                "Process all glob patterns case insensitively."            },
                         { "--no-glob-case-insensitive",                                             "no-glob-case-insensitive"                                 },
                         { "--heading",                                                              "Print matches grouped by each file."                      },
                         { "--no-heading",                                                           "Don't group matches by each file."                        },
    { "-.", hide=true }, { "--hidden",                                                               "Search hidden files and directories."                     },
                         { "--no-hidden",                                                            "no-hidden"                                                },
    { "-i", hide=true }, { "--ignore-case",                                                          "Case insensitive search."                                 },
                         { "--ignore-file-case-insensitive",                                         "Process ignore files case insensitively."                 },
                         { "--no-ignore-file-case-insensitive",                                      "no-ignore-file-case-insensitive"                          },
                         { "--include-zero",                                                         "Include files with zero matches in summary"               },
    { "-v", hide=true }, { "--invert-match",                                                         "Invert matching."                                         },
                         { "--json",                                                                 "Show search results in a JSON Lines format."              },
                         { "--no-json",                                                              "no-json"                                                  },
                         { "--line-buffered",                                                        "Force line buffering."                                    },
                         { "--no-line-buffered",                                                     "no-line-buffered"                                         },
    { "-n", hide=true }, { "--line-number",                                                          "Show line numbers."                                       },
    { "-N", hide=true }, { "--no-line-number",                                                       "Suppress line numbers."                                   },
    { "-x", hide=true }, { "--line-regexp",                                                          "Only show matches surrounded by line boundaries."         },
                         { "--max-columns-preview",                                                  "Print a preview for lines exceeding the limit."           },
                         { "--no-max-columns-preview",                                               "no-max-columns-preview"                                   },
                         { "--mmap",                                                                 "Search using memory maps when possible."                  },
                         { "--no-mmap",                                                              "Never use memory maps."                                   },
    { "-U", hide=true }, { "--multiline",                                                            "Enable matching across multiple lines."                   },
                         { "--no-multiline",                                                         "no-multiline"                                             },
                         { "--multiline-dotall",                                                     "Make '.' match new lines when multiline is enabled."      },
                         { "--no-multiline-dotall",                                                  "no-multiline-dotall"                                      },
                         { "--no-config",                                                            "Never read configuration files."                          },
                         { "--no-ignore",                                                            "Don't respect ignore files."                              },
                         { "--ignore",                                                               "ignore"                                                   },
                         { "--no-ignore-dot",                                                        "Don't respect .ignore files."                             },
                         { "--ignore-dot",                                                           "ignore-dot"                                               },
                         { "--no-ignore-exclude",                                                    "Don't respect local exclusion files."                     },
                         { "--ignore-exclude",                                                       "ignore-exclude"                                           },
                         { "--no-ignore-files",                                                      "Don't respect --ignore-file arguments."                   },
                         { "--ignore-files",                                                         "ignore-files"                                             },
                         { "--no-ignore-global",                                                     "Don't respect global ignore files."                       },
                         { "--ignore-global",                                                        "ignore-global"                                            },
                         { "--no-ignore-messages",                                                   "Suppress gitignore parse error messages."                 },
                         { "--ignore-messages",                                                      "ignore-messages"                                          },
                         { "--no-ignore-parent",                                                     "Don't respect ignore files in parent directories."        },
                         { "--ignore-parent",                                                        "ignore-parent"                                            },
                         { "--no-ignore-vcs",                                                        "Don't respect VCS ignore files."                          },
                         { "--ignore-vcs",                                                           "ignore-vcs"                                               },
                         { "--no-messages",                                                          "Suppress some error messages."                            },
                         { "--messages",                                                             "messages"                                                 },
                         { "--no-pcre2-unicode",                                                     "Disable Unicode mode for PCRE2 matching."                 },
                         { "--pcre2-unicode",                                                        "pcre2-unicode"                                            },
                         { "--no-require-git",                                                       "Do not require a git repository to use gitignores."       },
                         { "--require-git",                                                          "require-git"                                              },
                         { "--no-unicode",                                                           "Disable Unicode mode."                                    },
                         { "--unicode",                                                              "unicode"                                                  },
    { "-0", hide=true }, { "--null",                                                                 "Print a NUL byte after file paths."                       },
                         { "--null-data",                                                            "Use NUL as a line terminator instead of \n."              },
                         { "--one-file-system",                                                      "Do not descend into directories on other file systems."   },
                         { "--no-one-file-system",                                                   "no-one-file-system"                                       },
    { "-o", hide=true }, { "--only-matching",                                                        "Print only matched parts of a line."                      },
                         { "--passthru",                                                             "Print both matching and non-matching lines."              },
    { "-P", hide=true }, { "--pcre2",                                                                "Enable PCRE2 matching."                                   },
                         { "--no-pcre2",                                                             "no-pcre2"                                                 },
                         { "--pcre2-version",                                                        "Print the version of PCRE2 that ripgrep uses."            },
                         { "--no-pre",                                                               "no-pre"                                                   },
    { "-p", hide=true }, { "--pretty",                                                               "Alias for --color always --heading --line-number."        },
    { "-q", hide=true }, { "--quiet",                                                                "Do not print anything to stdout."                         },
    { "-z", hide=true }, { "--search-zip",                                                           "Search in compressed files."                              },
                         { "--no-search-zip",                                                        "no-search-zip"                                            },
    { "-S", hide=true }, { "--smart-case",                                                           "Smart case search."                                       },
                         { "--sort-files",                                                           "DEPRECATED"                                               },
                         { "--no-sort-files",                                                        "no-sort-files"                                            },
                         { "--stats",                                                                "Print statistics about this ripgrep search."              },
                         { "--no-stats",                                                             "no-stats"                                                 },
    { "-a", hide=true }, { "--text",                                                                 "Search binary files as if they were text."                },
                         { "--no-text",                                                              "no-text"                                                  },
                         { "--trim",                                                                 "Trim prefixed whitespace from matches."                   },
                         { "--no-trim",                                                              "no-trim"                                                  },
                         { "--type-list",                                                            "Show all supported file types."                           },
    { "-u", hide=true }, { "--unrestricted",                                                         "Reduce the level of 'smart' searching."                   },
                         { "--vimgrep",                                                              "Show results in vim compatible format."                   },
    { "-H", hide=true }, { "--with-filename",                                                        "Print the file path with the matched lines."              },
    { "-I", hide=true }, { "--no-filename",                                                          "Never print the file path with the matched lines."        },
    { "-w", hide=true }, { "--word-regexp",                                                          "Only show matches surrounded by word boundaries."         },
    { "-h", hide=true }, { "--help",                                                                 "Prints help information. Use --help for more details."    },
    { "-V", hide=true }, { "--version",                                                              "Prints version information"                               },
  })

@chrisant996
Copy link
Owner

@mjcarman Awesome, thanks for the settings and script. I'll look into them and report what I find.

Try pressing Ctrl-X Ctrl-Z and it will list a bunch of diagnostic info, which will begin with something like this:

version:
  version           1.4.15.17c615
  binaries          C:\wbin\clink
session:
  session           34720
  profile           C:\Users\chrisant\AppData\Local\clink
  log               C:\Users\chrisant\AppData\Local\clink\clink.log
  default_settings  C:\Users\chrisant\AppData\Local\clink\default_settings
  settings          C:\Users\chrisant\AppData\Local\clink\clink_settings
  history           C:\Users\chrisant\AppData\Local\clink\clink_history
  scripts           C:\wbin\clink ; C:\Users\chrisant\AppData\Local\clink
  default_inputrc   C:\Users\chrisant\AppData\Local\clink\default_inputrc
  inputrc           c:\wbin\clink\.inputrc

The default_inputrc line is where the set colored-stats on would come from.
Or it could be overridden by a file in the inputrc line.

The "Use enhanced defaults" option affects defaults, but any of them can be overridden by user configuration.

@chrisant996
Copy link
Owner

@mjcarman P.S. how would you feel about your ripgrep argmatcher being included in clink-completions?

@mjcarman
Copy link
Author

Diagnostic info:

version:
  version           1.4.14.b4934e
  binaries          C:\Program Files (x86)\clink
session:
  session           16936
  profile           C:\Users\Mike\AppData\Local\clink
  log               C:\Users\Mike\AppData\Local\clink\clink.log
  default_settings  C:\Program Files (x86)\clink\default_settings
  settings          C:\Users\Mike\AppData\Local\clink\clink_settings
  history           C:\Users\Mike\AppData\Local\clink\clink_history
  scripts           C:\Program Files (x86)\clink ; C:\Users\Mike\AppData\Local\clink ; C:\Users\Mike\AppData\Local\clink-completions
  default_inputrc   C:\Program Files (x86)\clink\default_inputrc
prompt refilter:
  refilter      2
  redisplay     1

default_inputrc:

# When this file is named "default_inputrc" and is in the binaries
# directory or profile directory, it provides enhanced default settings.

# Override the built-in Readline defaults with ones that provide a more
# enhanced Clink experience.

colored-completion-prefix                   on
colored-stats                               on
mark-symlinked-directories                  on
completion-auto-query-items                 on
history-point-at-end-of-anchored-search     on
search-ignore-case                          on

Which makes it look like colored-stats is set for me — it just wasn't listed in the clink set output. Looking at the documentation it's worth noting that I don't have the %LS_COLORS% environmental variable set, so having it set to on presumably doesn't do anything in my case.

@mjcarman
Copy link
Author

@chrisant996 Feel free to crib my ripgrep argmatcher and anything else you'd like from my fork of clink-completions.

@chrisant996
Copy link
Owner

@chrisant996 Feel free to crib my ripgrep argmatcher and anything else you'd like from my fork of clink-completions.

@mjcarman Oh hey, you might be interested in this:

ripgrep comes with a rg.fish file, which defines completions for use with the fish shell. And since ripgrep itself maintains the fish completions, it should always be up to date.

The clink-gizmos repo has a fishcomplete.lua script, which is off by default, but which is generally able to parse fish completion scripts, as long as they don't get too complicated (e.g. it can't run custom fish shell scripts, of course).

The fishcomplete.lua script is able to parse the rg.fish file and automatically produce a Clink argmatcher from it. I would say it's in a prototype stage, largely because I don't know how prevalent it is to have complex fish completion scripts that use more than just the complete command.

(Also, in your argmatcher, the hidden flags like -e and -A don't have linked argmatchers for their arguments. So parsing and completions won't behave quite right when using them.)

@mjcarman
Copy link
Author

@chrisant996 I was aware of ripgrep bundling completions for a few shells but not that there was a way to convert any of them into one for clink. Using something ripgrep provides as the truth source would certainly be preferable to error-prone manual updates. Another option would be using help_parser from clink-completions. The gnu parser does a pretty good job on the output of rg -h. (It chokes on the output from rg --help.) It misses stuff like the enumerated values taken by the --engine flag but gets the basic data right. It's a good option if you favor low maintenance and better compatibility with whatever version of ripgrep the user happens to have installed over more power via linked matchers.

I found myself wishing that there was a standard declarative syntax (e.g. in YAML) for completions that could be used for any shell, but obviously that be very limited even if it existed. I also debated contributing my rg.lua to the ripgrep repository but didn't want to re-implement it without using arghelper.

Thanks for pointing that out the missing linked matchers for hidden flags. I've updated my rg.lua to include them.

@chrisant996
Copy link
Owner

I also debated contributing my rg.lua to the ripgrep repository but didn't want to re-implement it without using arghelper.

So true. I need to make some decisions and add improved argmatcher syntax into Clink itself. I'll try to collect my design thoughts in a brief doc and email it to you for your thoughts in case you have time/interest to give feedback. (The exercise of putting my thoughts into document form will be helpful to me, regardless.)

@mjcarman
Copy link
Author

mjcarman commented Feb 1, 2023

I'll try to collect my design thoughts in a brief doc and email it to you for your thoughts in case you have time/interest to give feedback.

Sure; I'd be happy to.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants