aboutsummaryrefslogtreecommitdiff
path: root/autoload/repl.kak
blob: 10c236765cfd818aa6b48bb3b4cb31b0705be70c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
declare-user-mode repl
map global normal <c-t> ': enter-user-mode repl<ret>' -docstring 'Repl mode'
map global repl <tab> ': enter-user-mode repl-mode-select<ret>' -docstring 'Select repl'
map global repl <c-t> ': xrepl-begin<ret>' -docstring 'Start repl'
map global repl t ': xrepl-begin<ret>' -docstring 'Start repl'
map global repl l ': xrepl-send-command<ret>' -docstring 'Send to selection to repl'
map global repl <ret> ': xrepl-send-paragraph<ret>' -docstring 'Send paragraph to repl'
map global repl r ': xrepl-send-keys Enter<ret>' -docstring 'Send return key to repl'
map global repl c ': xrepl-send-keys C-c<ret>' -docstring 'Send Ctrl+c interrupt to repl'
map global repl p ': xrepl-send-prompt<ret>' -docstring 'Prompt for text to send to repl'
map global repl q ': xrepl-quit<ret>' -docstring 'Quit repl'

declare-option bool xrepl_running false;
declare-option str xrepl_current_name;
declare-option str xrepl_current_cmd;
declare-option str xrepl_current_transform;
declare-option bool xrepl_current_clear_screen false;

# TODO: Use register set to selection (paragraph) instead of selection
# TODO: Add env
# TODO: Migrate curly
# TODO: Preserve original selection with send paragraph
# TODO: Sometimes repl stops working (tmux repl id changed?)

declare-user-mode repl-mode-select
define-command define-repl-mode -params 4 %{
  # TODO: USe a hidden command and use for keymap
  map %arg{1} repl-mode-select %arg{2} -docstring %arg{3} %sh{
    kak_escape() { printf "'"; printf '%s' "$1" | sed "s/'/''/g"; printf "'"; }
    printf ": xrepl-quit<ret>"
    printf ": set global xrepl_current_name '$3'<ret>"
    printf ": set global xrepl_current_cmd \"\$SHELL\"<ret>"
    printf ": set global xrepl_current_transform \"\"<ret>"
    printf ": set global xrepl_current_clear_screen false<ret>"
    printf ": evaluate-commands $(kak_escape "$(echo "$4" | tr '\n' ';')")<ret>"
    # echo "$4" >> foobarity
    # echo "$(kak_escape "$(echo "$4" | tr '\n' ';')")" >> foobarity
    printf ": xrepl-begin<ret>"
  }
}

define-repl-mode global s 'Shell' %{ set global xrepl_current_cmd '$SHELL' }
define-repl-mode global n 'Node' %{ set global xrepl_current_cmd 'node' }
define-repl-mode global a 'AI: Local' %{ set global xrepl_current_cmd 'aichat' }
define-repl-mode global g 'AI: Gemini' %{ set global xrepl_current_cmd 'gemini' }

hook global BufSetOption filetype=haskell %{
  define-repl-mode buffer h 'Haskell: cabal test' %{
    set global xrepl_current_cmd 'cabal test'
    set global xrepl_current_clear_screen true
  }
}

hook global BufSetOption filetype=ruby %{
  define-repl-mode buffer r 'Rspec' %{
    # TODO: Make generic
    set global xrepl_current_cmd 'docker compose exec shape-api -T sh'
    set global xrepl_current_transform 'cat > /dev/null
      path="$kak_buffile"
      if [ $kak_cursor_line -gt 5 ]; then
        path="$path:$kak_cursor_line"
      fi
      echo "rspec -fd $path"
    '
    set global xrepl_current_clear_screen true
  }
}

hook global BufSetOption filetype=(?:javascript|typescript|jsx|tsx) %{
  define-repl-mode buffer c 'Cypress' %{
    set global xrepl_current_cmd '$SHELL'
    set global xrepl_current_transform 'cat > /dev/null
      echo "npx cypress run --headless --e2e --spec ''$kak_buffile'';"
    '
    set global xrepl_current_clear_screen true
  }
  define-repl-mode global j 'Jest' %{
    set global xrepl_current_cmd '$SHELL'
    set global xrepl_current_transform 'cat > /dev/null
      echo "sh -c \\"cd ''$(dirname "$kak_buffile")''; npx jest --runTestsByPath ''$kak_buffile''\\";"
    '
    set global xrepl_current_clear_screen true
  }
}

define-command xrepl-send-prompt %{
  prompt -buffer-completion 'Send to repl: ' %{ repl-send-text %val{text} }
}

define-command xrepl-send-command %{
  evaluate-commands -draft %sh{
    if [ "$kak_opt_xrepl_current_clear_screen" == "true" ]; then
      echo "xrepl-send-keys C-l"
    fi

    transform="$kak_opt_xrepl_current_transform"
    value="$kak_selection"
    if ! [ -z "$transform" ]; then
      export kak_buffile kak_selection kak_selection_desc kak_cursor_line kak_cursor_column
      value=$(echo "$kak_selection" | sh -c "$transform")
    fi
    echo -e "repl-send-text %{$value\n}"
  }
}

define-command xrepl-send-paragraph %{
  execute-keys '<a-i>p'
  xrepl-send-command
}

define-command xrepl-send-keys -params 1.. %{
  nop %sh{ tmux send-keys -t "$kak_opt_tmux_repl_id" "$@" }
}

define-command xrepl-quit %{
  set-option global xrepl_running false
  try %{ nop %sh{
    if ! [ -z "$kak_opt_tmux_repl_id" ]; then
      tmux kill-pane -t "$kak_opt_tmux_repl_id";
    fi
  } }
}

define-command xrepl-begin %{
  evaluate-commands %sh{
    if [ "$kak_opt_xrepl_running" = "false" ]; then
      init_cmd="$kak_opt_xrepl_current_cmd"
      if [ -z "$init_cmd" ]; then init_cmd="$SHELL"; fi
      echo "info %opt{xrepl_current_name}"
      echo "set-option global xrepl_running true"
      echo "repl-new -l 45% $init_cmd"
      echo "nop %sh{ tmux last-pane }"
    fi
  }
}