aboutsummaryrefslogtreecommitdiff
path: root/autoload/repl/repl.kak
blob: bd47a679ff8406fc0fe2690e52e6411fc86f6aa7 (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
136
137
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_tmux_id;
declare-option str xrepl_current_name;
declare-option str xrepl_current_cmd;
declare-option str xrepl_current_transform;
declare-option str xrepl_current_split_size;
declare-option bool xrepl_current_split_vertical false;
declare-option bool xrepl_current_clear_screen false;

# TODO: "Custom" repl mode
# TODO: Use register set to selection (paragraph) instead of selection
# TODO: Add env
# TODO: Preserve original selection with send paragraph

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

define-command xrepl-send-prompt %{
  prompt -buffer-completion 'Send to repl: ' %{ xrepl-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
      # Available values in transform script
      export kak_buffile kak_selection kak_selection_desc kak_cursor_line kak_cursor_column kak_config
      value=$(echo "$kak_selection" | sh -c "$transform")
    fi
    echo -e "xrepl-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_xrepl_tmux_id" "$@" }
}

define-command xrepl-quit %{
  set-option global xrepl_running false
  try %{ nop %sh{
    if ! [ -z "$kak_opt_xrepl_tmux_id" ]; then
      tmux kill-pane -t "$kak_opt_xrepl_tmux_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"
      cmd=$([ "$kak_opt_xrepl_current_split_vertical" == "true" ] && echo "tmux-xrepl-vertical" || echo "tmux-xrepl-horizontal")
      echo "$cmd -l $kak_opt_xrepl_current_split_size $init_cmd"
      echo "nop %sh{ tmux last-pane }"
    fi
  }
}

define-command -hidden -params 1.. tmux-xrepl-impl %{
  evaluate-commands %sh{
    if [ -z "$TMUX" ]; then
      echo 'fail This command is only available in a tmux session'
      exit
    fi
    tmux_args="split-window $1 -t ${kak_client_env_TMUX_PANE}"
    shift
    repl_pane_id=$(tmux $tmux_args -P -F '#{pane_id}' "$@")
    printf "set-option current xrepl_tmux_id '%s'" "$repl_pane_id"
  }
}

define-command tmux-xrepl-vertical -params 0.. %{ tmux-xrepl-impl '-v' %arg{@} }
define-command tmux-xrepl-horizontal -params 0.. %{ tmux-xrepl-impl '-h' %arg{@} }

define-command xrepl-send-text -params 0..1 %{
  evaluate-commands %sh{
    if [ $# -eq 0 ]; then
        tmux set-buffer -b kak_selection -- "${kak_selection}"
    else
        tmux set-buffer -b kak_selection -- "$1"
    fi
    tmux paste-buffer -b kak_selection -t "$kak_opt_xrepl_tmux_id" ||
    echo 'fail tmux-send-text: failed to send text, see *debug* buffer for details'
  }
}