Csv-mode

Hi!

I made a csv-mode giving colors to columns, which helps reading the the csv-file. Especially if the rows have clearly different lengths. Please, do take a look of the pics below.

csvcolors

ohlc_csv

The script is short and can be found below. At the moment it uses a fixed separator for columns that suits me, that is the ‘;’-character. And the colors are also fixed.

If you like this, it is easy to take and modify. I’d like to make this a bit more usable as an extra plugin (or even part of the official collection of modes). And I don’t mind at all if somebody handy takes and makes it. So:

  • How should the separator be provided as a parameter that the users can easily change on their kakrc?
  • How about the colors? How should the following code be modified so that it would use the color scheme the user has chosen? Or alternatively how to give an easy way to modify the colors?
  • The chosen mechanism to color the columns works for a number of columns but there is a limit. I tried some other ways without success to support clearly a larger number of columns (with different colors). Any hints or ideas how to do this?
  • Anything else to be considered that makes plugins nice to use?
# Detection
# ‾‾‾‾‾‾‾‾‾

hook global BufCreate .*[.](csv) %{
    set-option buffer filetype csv
}

# Highlighters
# ‾‾‾‾‾‾‾‾‾‾‾‾


add-highlighter shared/csv regions

add-highlighter shared/csv/comment region ^        \n   group
add-highlighter shared/csv/comment/ regex '(^[^\n;]*[;$])?([^\n;]*[;$])?([^\n;]*[;$])?([^\n;]*[;$])?([^\n;]*[;
$])?([^\n;]*[;$])?([^\n;]*[;$])?' 1:yellow 2:red 3:cyan 4:green 5:blue 6:rgb:993286 7:magenta

hook -group csv-highlight global WinSetOption filetype=csv %{
    add-highlighter window/csv ref csv
}

hook -group csv-highlight global WinSetOption filetype=(?!csv).* %{
    remove-highlighter window/csv
}
7 Likes

Nice one! You could use options to let the user alter the behavior. As for the number of columns: I think if there are enough colors (like you have), it should be fine if colors repeat.

There is another plugin that colors things repeatedly. It has some options to specify the colors and what to color. Maybe you can take some inspiration from it to create options for colors and a column separator:

Here you may finds the next version allowing a bit customization and the csv-enable can be used in kakrc like

csv-enable ','

I tried to produce the faces with sh-scrip from csv_faces and corresponding regex and feed them back to kakoune, but didn’t quite get it working. The variables look ok based on echo debugging but only the first column gets the color. Maybe something how faces should be initialized or exposed or something?

Anyhow, maybe this has a bit better usability now. I tried with two buffers that had different separators and it is not yet working very well in that kind of situations. (But at least it is easy to change the sep manually by first disabling and then enabling as necessary.)

declare-option str-list csv_faces "1:yellow" "2:red" "3:cyan" "4:green" "5:blue" "6:rgb:993286" "7:magenta"

# Detection
# ‾‾‾‾‾‾‾‾‾

# debug options

hook global BufCreate .*[.](csv) %{
    set-option buffer filetype csv
}

# Highlighters
# ‾‾‾‾‾‾‾‾‾‾‾‾

define-command csv-enable -params 1 %{
	declare-option -hidden regex csv_rgx "(^[^\n%arg{1}]*[%arg{1}$])?([^\n%arg{1}]*[%arg{1}$])?([^\n%arg{1
}]*[%arg{1}$])?([^\n%arg{1}]*[%arg{1}$])?([^\n%arg{1}]*[%arg{1}$])?([^\n%arg{1}]*[%arg{1}$])?([^\n%arg{1}]*[%a
rg{1}$])?"
	add-highlighter shared/csv regions
	add-highlighter shared/csv/comment region ^        \n   group
	# csv-prepare-rgx %arg{1}
	add-highlighter shared/csv/comment/ regex %opt{csv_rgx} %opt{csv_faces}
}

define-command csv-disable %{
	remove-highlighter shared/csv/comment/
	remove-highlighter shared/csv/comment
	remove-highlighter shared/csv 
}


hook -group csv-highlight global WinSetOption filetype=csv %{
    add-highlighter window/csv ref csv
}

hook -group csv-highlight global WinSetOption filetype=(?!csv).* %{
    remove-highlighter window/csv
}

1 Like

Nice. If you made the separator a defined option, you could have it set to something different in each buffer scope.

You can read more about options here:

Thanks for the tip! I read this and a page about scopes and highlighters.

This works now almost in the way as it should. I added csv_sep global option and changed the regex to use %opt{csv_sep}, removed the enable and disable definitions and moved all highlighter initializations into the hook, and changed the highlighter to use window instead of shared.

Now, it is possible to (given that ‘;’ is the default value for csv_sep)

  • open a csv and use ‘;’ as sep
  • give set-option window csv_sep ','
  • open a second csv that will use ‘,’ as sep

The following also seems to work:

  • open a csv and use ‘;’ as sep
  • open a second csv that will use ‘,’ as sep (this will be colored in wrong way now)
  • give set-option window csv_sep ',' on the second csv buffer to get the coloring correct

The only annoying thing is that debug buffer will get error message about highlighter
duplicate id’s. When opening a csv, if first uses csv_sep-hook, then csv-hook, and last the csv_sep-hook again. How to get rid of those? Maybe add buffer name to highlighter name? Or a kind of check if there already is an highlighter? Hmm, maybe just using the csv_sep-hook is enough (ok, more trials).

declare-option str csv_sep ';'

declare-option str-list csv_faces "1:yellow" "2:red" "3:cyan" "4:green" "5:blue" "6:rgb:993286" "7:magenta"

declare-option -hidden regex csv_rgx ""

# Detection
# ‾‾‾‾‾‾‾‾‾

# debug options

hook global BufCreate .*[.](csv) %{
    set-option buffer filetype csv
}

# Highlighters
# ‾‾‾‾‾‾‾‾‾‾‾‾

hook global WinSetOption csv_sep=.* %{
    remove-highlighter window/csv
    set-option window csv_rgx "(^[^\n%opt{csv_sep}]*[%opt{csv_sep}$])?([^\n%opt{csv_sep}]*[%opt{csv_sep}$])?([
^\n%opt{csv_sep}]*[%opt{csv_sep}$])?([^\n%opt{csv_sep}]*[%opt{csv_sep}$])?([^\n%opt{csv_sep}]*[%opt{csv_sep}$]
)?([^\n%opt{csv_sep}]*[%opt{csv_sep}$])?([^\n%opt{csv_sep}]*[%opt{csv_sep}$])?"
    add-highlighter window/csv regions
    add-highlighter window/csv/comment region ^        \n   group
    add-highlighter window/csv/comment/ regex %opt{csv_rgx} %opt{csv_faces}
}

hook -group csv-highlight global WinSetOption filetype=csv %{
    set-option window csv_rgx "(^[^\n%opt{csv_sep}]*[%opt{csv_sep}$])?([^\n%opt{csv_sep}]*[%opt{csv_sep}$])?([
^\n%opt{csv_sep}]*[%opt{csv_sep}$])?([^\n%opt{csv_sep}]*[%opt{csv_sep}$])?([^\n%opt{csv_sep}]*[%opt{csv_sep}$]
)?([^\n%opt{csv_sep}]*[%opt{csv_sep}$])?([^\n%opt{csv_sep}]*[%opt{csv_sep}$])?"
    add-highlighter window/csv regions
    add-highlighter window/csv/comment region ^        \n   group
    add-highlighter window/csv/comment/ regex %opt{csv_rgx} %opt{csv_faces}

}

hook -group csv-highlight global WinSetOption filetype=(?!csv).* %{
    remove-highlighter window/csv
}

Removing the csv-hook and just using the csv_sep-hook looks to be enough here. I’ll probably prepare a git repo out of this in couple of days.

I was able to make it a bit better with shell-script part (it constructs the regex based on color list) and now the csv-repo is ready. My original attemps to write the script failed because I didn’t see right away that of course the first regex pattern had to be line starting one and the next on the line not (even though I had written the regex that I tried to construct in a loop - anyhow, now it seems to work).

After this it was easier to get the hooks and enable and disable to work together.

I’ll make a separate announcement next with links to repo etc.