forked from simonpcouch/pal
-
Notifications
You must be signed in to change notification settings - Fork 0
/
pal-add-remove.R
98 lines (87 loc) · 2.96 KB
/
pal-add-remove.R
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
#' Registering pals
#'
#' @description
#' Users can create custom pals using the `.pal_add()` function; after passing
#' the function a role and prompt, the pal will be available in the
#' [pal addin][.init_addin].
#'
#' **Most users should not need to interact with these functions.**
#' [prompt_new()] and friends can be used to create prompts for new pals, and
#' those pals can be registered with pal using [directory_load()] and friends.
#' The pals created by those functions will be persistent across sessions.
#'
#' @param role A single string giving a descriptor of the pal's functionality.
# TODO: actually do this once elmer implements
#' @param prompt A single string giving the system prompt. In most cases, this
#' is a rather long string, containing several newlines.
# TODO: only add prefix when not supplied one
#' @param interface One of `"replace"`, `"prefix"`, or `"suffix"`, describing
#' how the pal will interact with the selection. For example, the
#' [cli pal][pal_cli] `"replace"`s the selection, while the
#' [roxygen pal][pal_roxygen] `"prefixes"` the selected code with documentation.
#'
#' @returns
#' `NULL`, invisibly. Called for its side effect: a pal with role `role`
#' is registered (or unregistered) with the pal package.
#'
#' @name pal_add_remove
#' @export
.pal_add <- function(
role,
prompt = NULL,
interface = c("replace", "prefix", "suffix")
) {
# TODO: need to check that there are no spaces (or things that can't be
# included in a variable name)
check_string(role, allow_empty = FALSE)
check_string(prompt)
# TODO: make this an elmer interpolate or an .md file
.stash_prompt(prompt, role)
parse_interface(interface, role)
invisible()
}
#' @rdname pal_add_remove
.pal_remove <- function(role) {
check_string(role)
if (!role %in% list_pals()) {
cli::cli_abort("No active pal with the given {.arg role}.")
}
env_unbind(
pal_env(),
c(paste0(".pal_prompt_", role), paste0(".pal_rs_", role))
)
if (paste0(".pal_last_", role) %in% names(pal_env())) {
env_unbind(pal_env(), paste0(".pal_last_", role))
}
invisible()
}
supported_interfaces <- c("replace", "prefix", "suffix")
# given an interface and role, attaches a function binding in pal's `.pal_env`
parse_interface <- function(interface, role, call = caller_env()) {
if (isTRUE(identical(interface, supported_interfaces))) {
interface <- interface[1]
}
if (isTRUE(
length(interface) != 1 ||
!interface %in% supported_interfaces
)) {
cli::cli_abort(
"{.arg interface} should be one of {.or {.val {supported_interfaces}}}.",
call = call
)
}
if (interface == "suffix") {
# TODO: implement suffixing
cli::cli_abort("Suffixing not implemented yet.", call = call)
}
.stash_binding(
role,
function(context = rstudioapi::getActiveDocumentContext()) {
do.call(
paste0("rs_", interface, "_selection"),
args = list(context = context, role = role)
)
}
)
paste0(".pal_rs_", role)
}