mzte-nv: port tsn-actions config to haxe

This commit is contained in:
LordMZTE 2024-10-30 09:37:17 +01:00
parent 2ecb8c9fff
commit b1c60fe4d9
Signed by: LordMZTE
GPG key ID: B64802DC33A64FF6
15 changed files with 192 additions and 143 deletions

View file

@ -1,55 +0,0 @@
(local (mztenv tsna tsna-actions tsna-helpers nullls)
(values (require :mzte_nv) (require :ts-node-action)
(require :ts-node-action.actions)
(require :ts-node-action.helpers) (require :null-ls)))
(local zig-padding {")" " %s"
"]" " %s"
"}" " %s"
"{" "%s "
"," "%s "
:= " %s "
:+ " %s "
:- " %s "
:* " %s "
:/ " %s "
:** " %s "
:++ " %s "})
(macro md-marker-fn [level]
`[{1 (fn [_#] ,(string.rep "#" level)) :name ,(.. "Convert to H" level)}])
(local int-toggle-action {1 #(mztenv.tsn_actions.intToggle (tsna-helpers.node_text $1))
:name "Toggle Dec/Hex"})
(local int-to-hex-action {1 #(mztenv.tsn_actions.intToHex (tsna-helpers.node_text $1))
:name "Convert to Hex"})
(local int-to-dec-action {1 #(mztenv.tsn_actions.intToDec (tsna-helpers.node_text $1))
:name "Convert to Decimal"})
(tsna.setup {:zig {:FnCallArguments (tsna-actions.toggle_multiline zig-padding)
:InitList (tsna-actions.toggle_multiline zig-padding)
:VarDecl [{1 #(mztenv.tsn_actions.zigToggleMutability (tsna-helpers.node_text $1))
:name "Toggle Mutability"}]
:INTEGER [int-toggle-action]}
:markdown {:atx_h1_marker (md-marker-fn 2)
:atx_h2_marker (md-marker-fn 3)
:atx_h3_marker (md-marker-fn 4)
:atx_h4_marker (md-marker-fn 5)
:atx_h5_marker (md-marker-fn 6)
:atx_h6_marker (md-marker-fn 1)}
:java {:hex_integer_literal [int-to-dec-action]
:decimal_integer_literal [int-to-hex-action]}
:c {:number_literal [int-toggle-action]}
:cpp {:number_literal [int-toggle-action]}
:lua {:number [int-toggle-action]}
:fennel {:number [int-toggle-action]}})
(nullls.register {:name :TSNA
:method [(. nullls :methods :CODE_ACTION)]
:filetypes [:_all]
:generator {:fn (. tsna :available_actions)}})
(vim.keymap.set :n :U (. tsna :node_action)
(. (require :mzte_nv) :utils :map_opt))

View file

@ -1,15 +0,0 @@
package;
import lua.Table;
abstract DynTable(AnyTable) from AnyTable to AnyTable {
public inline function new() {
this = Table.create();
}
@:arrayAccess
public inline function get(k:Dynamic):Dynamic return this[untyped k];
@:arrayAccess
public inline function set(k:Dynamic, v:Dynamic) this[untyped k] = v;
}

View file

@ -0,0 +1,17 @@
package;
import lua.Table;
class StaticTools {
public static inline function toTable<K, V>(map:Map<K, V>):Table<K, V> {
return (untyped map : Dynamic).h;
}
/**
Removes Haxe metadata from tables for picky lua functions.
See: https://github.com/HaxeFoundation/haxe/issues/11805
**/
public static inline function removeMeta(x:Dynamic) {
cast(x, AnyTable).__fields__ = null;
}
}

View file

@ -1,5 +1,6 @@
package ext.mzte_nv;
extern class CPBuf {
@:luaDotMethod
function copyBuf():Void;
}

View file

@ -8,6 +8,8 @@ extern class MZTENv {
public static var cpbuf:CPBuf;
public static var compile:Compile;
public static var tsn_actions:TSNActions;
public static var utils:Utils;
@:luaDotMethod
public static function onInit():Void;

View file

@ -0,0 +1,15 @@
package ext.mzte_nv;
extern class TSNActions {
@:luaDotMethod
function zigToggleMutability(s:String):String;
@:luaDotMethod
function intToggle(s:String):String;
@:luaDotMethod
function intToHex(s:String):String;
@:luaDotMethod
function intToDec(s:String):String;
}

View file

@ -0,0 +1,5 @@
package ext.mzte_nv;
extern class Utils {
var map_opt:Dynamic;
}

View file

@ -1,6 +1,6 @@
package ext.vim;
import lua.Table.AnyTable;
using StaticTools;
typedef CreateUserCommandOptions = {
// incomplete
@ -12,17 +12,9 @@ private extern class ApiExt {
function nvim_create_user_command(name:String, command:Dynamic, opts:CreateUserCommandOptions):Void;
}
/**
Removes Haxe metadata from tables for picky lua functions.
See: https://github.com/HaxeFoundation/haxe/issues/11805
**/
private inline function removeMeta(x:Dynamic) {
cast(x, AnyTable).__fields__ = null;
}
abstract Api(ApiExt) {
public inline function createUserCommand(name:String, command:Dynamic, opts:CreateUserCommandOptions) {
removeMeta(opts);
opts.removeMeta();
this.nvim_create_user_command(name, command, opts);
}
}

View file

@ -0,0 +1,18 @@
package ext.vim;
import haxe.Constraints.Function;
import haxe.extern.EitherType;
using StaticTools;
private extern class KeymapExt {
@:luaDotMethod
function set(mode:String, bind:String, handler:EitherType<String, Function>, options:Dynamic):Void;
}
abstract Keymap(KeymapExt) {
public inline function set(mode:String, bind:String, handler:EitherType<String, Function>, options:Dynamic):Void {
options.removeMeta();
this.set(mode, bind, handler, options);
}
}

View file

@ -15,6 +15,7 @@ enum abstract LogLevel(Int) {
extern class Vim {
public static var loop:Loop;
public static var api:Api;
public static var keymap:Keymap;
public static var env:Table<String, String>;
public static var opt:Table<String, Opt>;

View file

@ -1,20 +1,14 @@
package init;
#if !macro
import plugins.*;
import haxe.Exception;
import ext.mzte_nv.MZTENv;
import ext.vim.Vim;
import lua.Table.AnyTable;
using lua.PairTools;
#end
import haxe.Exception;
import haxe.macro.Context;
import haxe.macro.Expr;
using Lambda;
#if !macro
class Plugins {
var startupPlugins:Array<IPlugin>;
var deferredPlugins:Array<IPlugin>;
@ -22,9 +16,13 @@ class Plugins {
var errors:Array<{plug:IPlugin, err:Exception}> = [];
public function new() {
regPlugins(["Nu", "Autopairs", "Catppuccin"]);
this.deferredPlugins = this.deferredPlugins.concat([
this.startupPlugins = [];
this.deferredPlugins = [
new PAutopairs(),
new PCatppuccin(),
new PNu(),
new PTSNActions(),
].concat([
"cmp",
"dap",
"devicons",
@ -44,7 +42,6 @@ class Plugins {
"telescope",
"treesitter",
"ts-context",
"tsn-actions",
"tterm",
"ufo",
].map(n -> (new LuaPlugin(n) : IPlugin)));
@ -94,51 +91,3 @@ class Plugins {
}
}
}
#end
private macro function regPlugins(names:Array<String>):Expr {
var startupPlugins = [];
var deferredPlugins = [];
for (name in names) {
final cl = Context.getType('plugins.P${name}');
switch (cl) {
case TInst(inst, _):
final params = inst.get().meta.extract("plugin")[0].params;
switch (params) {
case [{expr: EConst(CInt(prio, _))}, {expr: EConst(CIdent(startup))}]:
if (startup == "true") {
startupPlugins.push({prio: Std.parseInt(prio), type: inst.get()});
} else {
deferredPlugins.push({prio: Std.parseInt(prio), type: inst.get()});
}
default:
Context.error("Invalid params", inst.get().meta.extract("plugin")[0].pos);
}
default:
}
}
startupPlugins.sort((a, b) -> a.prio - b.prio);
deferredPlugins.sort((a, b) -> a.prio - b.prio);
final makeConstructorCall = (p) -> {
final tpath = {
params: null,
sub: null,
name: p.type.name,
pack: p.type.pack
};
return macro new $tpath();
};
final startupPluginExpr = [for (p in startupPlugins) makeConstructorCall(p)];
final deferredPluginExpr = [for (p in deferredPlugins) makeConstructorCall(p)];
return macro {
this.startupPlugins = $a{startupPluginExpr};
this.deferredPlugins = $a{deferredPluginExpr};
};
}

View file

@ -2,7 +2,6 @@ package plugins;
import lua.Lua;
@plugin(50, false)
class PAutopairs implements IPlugin {
public var name:String = "Autopairs";

View file

@ -4,7 +4,6 @@ import lua.Table;
import ext.vim.Vim;
import lua.Lua;
@plugin(20, false)
class PCatppuccin implements IPlugin {
public var name:String = "Catppuccin";

View file

@ -2,7 +2,6 @@ package plugins;
import lua.Lua;
@plugin(50, false)
class PNu implements IPlugin {
public var name:String = "Nushell";
public function new() {}

View file

@ -0,0 +1,122 @@
package plugins;
import ext.vim.Vim;
import ext.mzte_nv.MZTENv;
import lua.Lua;
import lua.Table;
using StaticTools;
using StringTools;
using lua.NativeStringTools;
class PTSNActions implements IPlugin {
public var name:String = "Tree-Sitter Node Actions";
public var zig_padding:Table<String, String> = [
")" => " %s",
"]" => " %s",
"}" => " %s",
"{" => "%s ",
"," => "%s ",
"=" => " %s ",
"+" => " %s ",
"-" => " %s ",
"*" => " %s ",
"/" => " %s ",
"**" => " %s ",
"++" => " %s ",
].toTable();
private var tsna_helpers:Dynamic;
public function new() {}
public function init() {
final tsna = Lua.require("ts-node-action");
final tsna_actions = Lua.require("ts-node-action.actions");
this.tsna_helpers = Lua.require("ts-node-action.helpers");
final nullls = Lua.require("null-ls");
final zig_multiline_action = tsna_actions[untyped "toggle_multiline"](this.zig_padding);
final toggle_int_action = Table.create([
Table.create(
[(node) -> MZTENv.tsn_actions.intToggle(this.tsna_helpers[untyped "node_text"](node))],
{name: "Toggle Dec/Hex"}
)
]);
tsna[untyped "setup"]({
zig: {
call_expression: zig_multiline_action,
struct_declaration: zig_multiline_action,
initializer_list: zig_multiline_action,
variable_declaration: Table.create([
Table.create(
[(node) -> MZTENv.tsn_actions.zigToggleMutability(this.tsna_helpers[untyped "node_text"](node))],
{
name: "Toggle Mutability",
}
)
]),
integer: toggle_int_action,
},
markdown: [for (i in 1...7) 'atx_h${i}_marker' => {
final next = i == 6 ? 1 : i + 1;
Table.create([_ -> NativeStringTools.rep("#", next)], {
name: 'Convert to H$next'
});
}].toTable(),
java: {
hex_integer_literal: Table.create(
[
Table.create(
[(node) -> MZTENv.tsn_actions.intToDec(this.tsna_helpers[untyped "node_text"](node))],
{
name: "Convert to Decimal",
}
)
]
),
decimal_integer_literal: Table.create([Table.create([(node) ->
MZTENv.tsn_actions.intToHex(this.tsna_helpers[untyped "node_text"](node))], {
name: "Convert to Hexadecimal",
})]),
},
c: {
number_literal: toggle_int_action,
},
cpp: {
number_literal: toggle_int_action,
},
lua: {
number: toggle_int_action,
},
fennel: {
number: toggle_int_action,
},
typst: {
math: Table.create([Table.create([toggleTypstMath], {name: "Expand/Contract math"})])
},
});
nullls[untyped "register"]({
name: "TSNA",
method: Table.create([(cast nullls : Dynamic).methods.CODE_ACTION]),
filetypes: Table.create(["_all"]),
generator: {fn: tsna[untyped "available_actions"]},
});
Vim.keymap.set("n", "U", tsna[untyped "node_action"], MZTENv.utils.map_opt);
}
private function toggleTypstMath(node:Dynamic):String {
final text:String = this.tsna_helpers[untyped "node_text"](node);
final sub1 = text.gsub("^%$%s+(.*)%s+%$$", "%$%1%$");
if (sub1 == text) {
// This assignment is necessary because haxe doesn't realize that gsub is a multireturn.
// TODO: open issue about this
final sub2 = text.gsub("^%$", "%$ ").gsub("%$$", " %$");
return sub2;
} else return sub1;
}
}