mirror of
https://github.com/leporello-js/leporello-js
synced 2026-01-13 13:04:30 -08:00
make cursor position controlled property of state
This commit is contained in:
@@ -13,6 +13,25 @@ export const pp_calltree = tree => ({
|
||||
children: tree.children && tree.children.map(pp_calltree)
|
||||
})
|
||||
|
||||
export const current_caret_position = state =>
|
||||
state.caret_position_by_file[state.current_module]
|
||||
// When we open file for the first time, caret set to the beginning
|
||||
?? 0
|
||||
|
||||
export const set_caret_position = (state, caret_position) => (
|
||||
{
|
||||
...state,
|
||||
caret_position_by_file: {
|
||||
...state.caret_position_by_file, [state.current_module]: caret_position
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
export const set_location = (state, location) => set_caret_position(
|
||||
{...state, current_module: location.module},
|
||||
location.index
|
||||
)
|
||||
|
||||
const is_stackoverflow = node =>
|
||||
// Chrome
|
||||
node.error.message == 'Maximum call stack size exceeded'
|
||||
@@ -214,35 +233,31 @@ const jump_calltree_node = (_state, _current_calltree_node) => {
|
||||
: find_callsite(next.modules, active_calltree_node, current_calltree_node)
|
||||
|
||||
return {
|
||||
state: {...next, current_module: loc.module},
|
||||
state: next.current_calltree_node.toplevel
|
||||
? {...next, current_module: loc.module}
|
||||
// TODO: better jump not start of function (arguments), but start
|
||||
// of body?
|
||||
: set_location(next, loc),
|
||||
effects: next.current_calltree_node.toplevel
|
||||
? {type: 'unembed_value_explorer'}
|
||||
: [
|
||||
{
|
||||
type: 'set_caret_position',
|
||||
// TODO: better jump not start of function (arguments), but start
|
||||
// of body?
|
||||
args: [loc.index],
|
||||
},
|
||||
{
|
||||
type: 'embed_value_explorer',
|
||||
args: [{
|
||||
index: loc.index,
|
||||
result: {
|
||||
ok: true,
|
||||
value: current_calltree_node.ok
|
||||
? {
|
||||
'*arguments*': current_calltree_node.args,
|
||||
'*return*': current_calltree_node.value,
|
||||
}
|
||||
: {
|
||||
'*arguments*': current_calltree_node.args,
|
||||
'*throws*': current_calltree_node.error,
|
||||
}
|
||||
}
|
||||
}],
|
||||
},
|
||||
]
|
||||
: {
|
||||
type: 'embed_value_explorer',
|
||||
args: [{
|
||||
index: loc.index,
|
||||
result: {
|
||||
ok: true,
|
||||
value: current_calltree_node.ok
|
||||
? {
|
||||
'*arguments*': current_calltree_node.args,
|
||||
'*return*': current_calltree_node.value,
|
||||
}
|
||||
: {
|
||||
'*arguments*': current_calltree_node.args,
|
||||
'*throws*': current_calltree_node.error,
|
||||
}
|
||||
}
|
||||
}],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -716,8 +731,8 @@ const select_return_value = state => {
|
||||
if(return_statement == null) {
|
||||
// Fn has no return statement
|
||||
return {
|
||||
state: {...state, current_module: loc.module},
|
||||
effects: {type: 'set_caret_position', args: [code.body.index, true]}
|
||||
state: set_location(state, {module: loc.module, index: code.body.index}),
|
||||
effects: {type: 'set_focus'}
|
||||
}
|
||||
} else {
|
||||
result_node = return_statement.children[0]
|
||||
@@ -743,15 +758,15 @@ const select_return_value = state => {
|
||||
}
|
||||
|
||||
return {
|
||||
state: {...state,
|
||||
current_module: loc.module,
|
||||
state: {
|
||||
...set_location(state, {module: loc.module, index: node.index}),
|
||||
selection_state: {
|
||||
node,
|
||||
initial_is_expand: true,
|
||||
result: result_node.result,
|
||||
}
|
||||
},
|
||||
effects: {type: 'set_caret_position', args: [node.index, true]}
|
||||
effects: {type: 'set_focus'}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -785,15 +800,17 @@ const select_arguments = (state, with_focus = true) => {
|
||||
}
|
||||
|
||||
return {
|
||||
state: {...state,
|
||||
current_module: loc.module,
|
||||
state: {
|
||||
...set_location(state, {module: loc.module, index: node.index}),
|
||||
selection_state: {
|
||||
node,
|
||||
initial_is_expand: true,
|
||||
result,
|
||||
}
|
||||
},
|
||||
effects: {type: 'set_caret_position', args: [node.index, with_focus]}
|
||||
effects: with_focus
|
||||
? {type: 'set_focus'}
|
||||
: null,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
112
src/cmd.js
112
src/cmd.js
@@ -14,7 +14,8 @@ import {
|
||||
calltree_commands,
|
||||
add_frame, calltree_node_loc, expand_path,
|
||||
initial_calltree_node, default_expand_path, toggle_expanded, active_frame,
|
||||
find_call, find_call_node, set_active_calltree_node
|
||||
find_call, find_call_node, set_active_calltree_node,
|
||||
set_caret_position, current_caret_position, set_location
|
||||
} from './calltree.js'
|
||||
|
||||
const collect_logs = call =>
|
||||
@@ -46,7 +47,7 @@ const apply_eval_result = (state, eval_result) => {
|
||||
}
|
||||
}
|
||||
|
||||
const run_code = (s, index, dirty_files) => {
|
||||
const run_code = (s, dirty_files) => {
|
||||
|
||||
const parse_result = load_modules(s.entrypoint, module => {
|
||||
if(dirty_files != null && dirty_files.includes(module)) {
|
||||
@@ -107,7 +108,6 @@ const run_code = (s, index, dirty_files) => {
|
||||
// Trigger loading of external modules
|
||||
return {...state,
|
||||
loading_external_imports_state: {
|
||||
index,
|
||||
external_imports,
|
||||
}
|
||||
}
|
||||
@@ -122,25 +122,29 @@ const run_code = (s, index, dirty_files) => {
|
||||
state.external_imports_cache,
|
||||
(module_name, module) => external_imports.includes(module_name)
|
||||
),
|
||||
index
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const do_external_imports_loaded = (
|
||||
state,
|
||||
const external_imports_loaded = (
|
||||
s,
|
||||
prev_state,
|
||||
external_imports,
|
||||
index,
|
||||
) => {
|
||||
if(
|
||||
state.loading_external_imports_state
|
||||
s.loading_external_imports_state
|
||||
!=
|
||||
prev_state.loading_external_imports_state
|
||||
) {
|
||||
// code was modified after loading started, discard
|
||||
return state
|
||||
return s
|
||||
}
|
||||
|
||||
const state = {
|
||||
...s,
|
||||
external_imports_cache: external_imports,
|
||||
loading_external_imports_state: null
|
||||
}
|
||||
|
||||
if(external_imports != null) {
|
||||
@@ -168,7 +172,7 @@ const do_external_imports_loaded = (
|
||||
}
|
||||
}
|
||||
|
||||
const node = find_call_node(state, index)
|
||||
const node = find_call_node(state, current_caret_position(state))
|
||||
|
||||
let active_calltree_node, next
|
||||
|
||||
@@ -239,35 +243,12 @@ const do_external_imports_loaded = (
|
||||
}
|
||||
}
|
||||
|
||||
const external_imports_loaded = (
|
||||
state,
|
||||
prev_state,
|
||||
external_imports,
|
||||
maybe_index,
|
||||
) => {
|
||||
// index saved in loading_external_imports_state maybe stale, if cursor was
|
||||
// moved after
|
||||
// TODO refactor, make index controlled property saved in state?
|
||||
const index = maybe_index ?? state.loading_external_imports_state.index
|
||||
|
||||
// TODO after edit we should fire embed_value_explorer, but we dont do it
|
||||
// here because we dont have cursor position (index) here (see comment
|
||||
// above). Currently it is fixed by having `external_imports_cache`, so code
|
||||
// goes async path only on first external imports load
|
||||
return {
|
||||
...do_external_imports_loaded(state, prev_state, external_imports, index),
|
||||
external_imports_cache: external_imports,
|
||||
loading_external_imports_state: null
|
||||
}
|
||||
}
|
||||
|
||||
// TODO refactor, make index controlled property and get it from state instead
|
||||
// of setting to zero
|
||||
const rerun_code = state => run_code(state, 0)
|
||||
|
||||
const input = (state, code, index) => {
|
||||
const files = {...state.files, [state.current_module]: code}
|
||||
const next = run_code({...state, files}, index, [state.current_module])
|
||||
const next = run_code(
|
||||
set_caret_position({...state, files}, index),
|
||||
[state.current_module]
|
||||
)
|
||||
const effect_save = next.current_module == ''
|
||||
? {type: 'save_to_localstorage', args: ['code', code]}
|
||||
: {type: 'write', args: [
|
||||
@@ -505,13 +486,12 @@ const change_current_module = (state, current_module) => {
|
||||
}
|
||||
}
|
||||
|
||||
const change_entrypoint = (state, entrypoint, index) => {
|
||||
const change_entrypoint = (state, entrypoint) => {
|
||||
return run_code(
|
||||
{...state,
|
||||
entrypoint,
|
||||
current_module: entrypoint,
|
||||
},
|
||||
index
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -543,8 +523,10 @@ const goto_definition = (state, index) => {
|
||||
loc = {module: state.current_module, index: d.index}
|
||||
}
|
||||
return {
|
||||
state: {...state, current_module: loc.module},
|
||||
effects: {type: 'set_caret_position', args: [loc.index]}
|
||||
state: set_caret_position(
|
||||
{...state, current_module: loc.module},
|
||||
loc.index,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -553,9 +535,8 @@ const goto_definition = (state, index) => {
|
||||
|
||||
const goto_problem = (state, p) => {
|
||||
return {
|
||||
state: {...state, current_module: p.module},
|
||||
// TODO set focus after jump
|
||||
effects: {type: 'set_caret_position', args: [p.index]}
|
||||
state: set_location(state, p),
|
||||
effects: {type: 'set_focus'}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -728,17 +709,20 @@ const do_move_cursor = (state, index) => {
|
||||
}
|
||||
|
||||
const move_cursor = (s, index) => {
|
||||
|
||||
const with_cursor = set_caret_position(s, index)
|
||||
|
||||
if(!s.parse_result.ok){
|
||||
return {state: s}
|
||||
return {state: with_cursor}
|
||||
}
|
||||
|
||||
if(s.loading_external_imports_state != null) {
|
||||
// TODO: save index in loading_external_imports_state
|
||||
return {state: s}
|
||||
// Code will be executed when imports will load, do not do it right now
|
||||
return {state: with_cursor}
|
||||
}
|
||||
|
||||
// Remove selection on move cursor
|
||||
const state_sel_removed = {...s, selection_state: null}
|
||||
const state_sel_removed = {...with_cursor, selection_state: null}
|
||||
|
||||
const state = find_call(state_sel_removed, index)
|
||||
|
||||
@@ -784,7 +768,7 @@ const do_load_dir = (state, dir) => {
|
||||
|
||||
const load_dir = (state, dir) => {
|
||||
// Clear parse cache and rerun code
|
||||
return rerun_code({
|
||||
return run_code({
|
||||
...do_load_dir(state, dir),
|
||||
// remove cache. We have to clear cache because imports of modules that are
|
||||
// not available because project_dir is not available have errors and the
|
||||
@@ -800,7 +784,7 @@ const create_file = (state, dir, current_module) => {
|
||||
const open_run_window = state => {
|
||||
// After we reopen run window, we should reload external modules in the
|
||||
// context of new window. Clear external_imports_cache
|
||||
return rerun_code({
|
||||
return run_code({
|
||||
...state,
|
||||
external_imports_cache: null,
|
||||
})
|
||||
@@ -811,23 +795,21 @@ const get_initial_state = state => {
|
||||
? state
|
||||
: do_load_dir(state, state.project_dir)
|
||||
|
||||
const entrypoint = with_files.entrypoint
|
||||
const current_module = with_files.current_module
|
||||
const html_file = with_files.html_file
|
||||
const blank_if_not_exists = key =>
|
||||
with_files.files[with_files[key]] == null
|
||||
? ''
|
||||
: with_files[key]
|
||||
|
||||
const entrypoint = blank_if_not_exists('entrypoint')
|
||||
const current_module = blank_if_not_exists('current_module')
|
||||
const html_file = blank_if_not_exists('html_file')
|
||||
|
||||
return {
|
||||
...with_files,
|
||||
// If module for entrypoint or current_module does not exist, use *scratch*
|
||||
entrypoint:
|
||||
with_files.files[entrypoint] == null
|
||||
? ''
|
||||
: entrypoint,
|
||||
current_module: with_files.files[current_module] == null
|
||||
? ''
|
||||
: current_module,
|
||||
html_file: with_files.files[html_file] == null
|
||||
? ''
|
||||
: html_file,
|
||||
entrypoint,
|
||||
current_module,
|
||||
html_file,
|
||||
caret_position_by_file: {[current_module]: 0},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -416,9 +416,9 @@ export class Editor {
|
||||
? this.ace_editor.getSession()
|
||||
: this.get_session(file)
|
||||
|
||||
// Session was not created for file
|
||||
if(session == null) {
|
||||
return null
|
||||
// Session was not created for file
|
||||
throw new Error('illegal state')
|
||||
}
|
||||
|
||||
return session.doc.positionToIndex(session.selection.getCursor())
|
||||
|
||||
@@ -240,11 +240,7 @@ export class UI {
|
||||
|
||||
change_entrypoint(e) {
|
||||
const file = e.target.value
|
||||
const index = this.editor.get_caret_position(file)
|
||||
// if index is null, session was not created, and index after session
|
||||
// creation will be 0
|
||||
?? 0
|
||||
exec('change_entrypoint', file, index)
|
||||
exec('change_entrypoint', file)
|
||||
this.editor.focus()
|
||||
}
|
||||
|
||||
|
||||
12
src/effects.js
vendored
12
src/effects.js
vendored
@@ -5,6 +5,7 @@ import {
|
||||
calltree_node_loc,
|
||||
get_deferred_calls
|
||||
} from './calltree.js'
|
||||
import {current_caret_position} from './calltree.js'
|
||||
import {FLAGS} from './feature_flags.js'
|
||||
import {exec, FILES_ROOT} from './index.js'
|
||||
|
||||
@@ -165,6 +166,10 @@ export const render_common_side_effects = (prev, next, command, ui) => {
|
||||
ui.editor.switch_session(next.current_module)
|
||||
}
|
||||
|
||||
if(current_caret_position(next) != ui.editor.get_caret_position()) {
|
||||
ui.editor.set_caret_position(current_caret_position(next))
|
||||
}
|
||||
|
||||
if(prev.loading_external_imports_state != next.loading_external_imports_state) {
|
||||
load_external_imports(next)
|
||||
}
|
||||
@@ -263,11 +268,8 @@ export const render_common_side_effects = (prev, next, command, ui) => {
|
||||
|
||||
|
||||
export const EFFECTS = {
|
||||
set_caret_position: (state, [index, with_focus], ui) => {
|
||||
ui.editor.set_caret_position(index)
|
||||
if(with_focus) {
|
||||
ui.editor.focus()
|
||||
}
|
||||
set_focus: (_state, _args, ui) => {
|
||||
ui.editor.focus()
|
||||
},
|
||||
|
||||
set_status: (state, [msg], ui) => {
|
||||
|
||||
109
test/test.js
109
test/test.js
@@ -2,8 +2,13 @@ import {find_leaf, ancestry, find_node} from '../src/ast_utils.js'
|
||||
import {parse, print_debug_node} from '../src/parse_js.js'
|
||||
import {eval_tree, eval_frame, eval_modules} from '../src/eval.js'
|
||||
import {COMMANDS} from '../src/cmd.js'
|
||||
import {root_calltree_node, active_frame, pp_calltree, get_deferred_calls}
|
||||
from '../src/calltree.js'
|
||||
import {
|
||||
root_calltree_node,
|
||||
active_frame,
|
||||
pp_calltree,
|
||||
get_deferred_calls,
|
||||
current_caret_position,
|
||||
} from '../src/calltree.js'
|
||||
import {color_file} from '../src/color.js'
|
||||
import {
|
||||
test,
|
||||
@@ -863,7 +868,6 @@ export const tests = [
|
||||
console.log(foo_var)
|
||||
`
|
||||
const s1 = test_initial_state(code)
|
||||
assert_equal(s1.loading_external_imports_state.index, 0)
|
||||
assert_equal(s1.loading_external_imports_state.external_imports, ['foo.js'])
|
||||
|
||||
const state = COMMANDS.external_imports_loaded(s1, s1, {
|
||||
@@ -897,7 +901,6 @@ export const tests = [
|
||||
// embed_value_explorer suspended until external imports resolved
|
||||
assert_equal(effects.length, 1)
|
||||
assert_equal(effects[0].type, 'save_to_localstorage')
|
||||
assert_equal(state.loading_external_imports_state.index, index)
|
||||
assert_equal(
|
||||
state.loading_external_imports_state.external_imports,
|
||||
['foo.js'],
|
||||
@@ -1106,18 +1109,11 @@ export const tests = [
|
||||
|
||||
const x_result_1 = COMMANDS.goto_definition(s, entry.indexOf('x*x'))
|
||||
assert_equal(x_result_1.state.current_module, '')
|
||||
assert_equal(
|
||||
x_result_1.effects,
|
||||
{type: 'set_caret_position', args: [entry.indexOf('x')]}
|
||||
)
|
||||
assert_equal(current_caret_position(x_result_1.state), entry.indexOf('x'))
|
||||
|
||||
const x_result_2 = COMMANDS.goto_definition(s, entry.indexOf('x'))
|
||||
assert_equal(x_result_2.state.current_module, 'a')
|
||||
assert_equal(
|
||||
x_result_2.effects,
|
||||
{type: 'set_caret_position', args: [a.indexOf('x = 2')]}
|
||||
)
|
||||
|
||||
assert_equal(current_caret_position(x_result_2.state), a.indexOf('x = 2'))
|
||||
}),
|
||||
|
||||
test('assignment', () => {
|
||||
@@ -1183,11 +1179,8 @@ export const tests = [
|
||||
const {state, effects} = COMMANDS.step_into(initial, code.indexOf('x()'))
|
||||
const call_code = state.current_calltree_node.code
|
||||
assert_equal(call_code.index, code.indexOf('() =>'))
|
||||
assert_equal(effects[0], {
|
||||
type: 'set_caret_position',
|
||||
args: [code.indexOf('() =>')],
|
||||
})
|
||||
assert_equal(effects[1].type, 'embed_value_explorer')
|
||||
assert_equal(current_caret_position(state), code.indexOf('() =>'))
|
||||
assert_equal(effects.type, 'embed_value_explorer')
|
||||
}),
|
||||
|
||||
test('step_into deepest', () => {
|
||||
@@ -1587,28 +1580,26 @@ const y = x()`
|
||||
const index = 0 // Where call starts
|
||||
const call = root_calltree_node(s).children[0]
|
||||
const {state, effects} = COMMANDS.calltree.click(s, call.id)
|
||||
assert_equal(current_caret_position(state), index)
|
||||
assert_equal(
|
||||
effects,
|
||||
[
|
||||
{ type: 'set_caret_position', args: [ index ] },
|
||||
{
|
||||
"type": "embed_value_explorer",
|
||||
"args": [
|
||||
{
|
||||
index,
|
||||
result: {
|
||||
"ok": true,
|
||||
"value": {
|
||||
"*arguments*": [
|
||||
[]
|
||||
],
|
||||
"*return*": {}
|
||||
}
|
||||
{
|
||||
"type": "embed_value_explorer",
|
||||
"args": [
|
||||
{
|
||||
index,
|
||||
result: {
|
||||
"ok": true,
|
||||
"value": {
|
||||
"*arguments*": [
|
||||
[]
|
||||
],
|
||||
"*return*": {}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
}),
|
||||
|
||||
@@ -1624,10 +1615,7 @@ const y = x()`
|
||||
const assert_loc = (s, substring, is_assert_node_by_loc) => {
|
||||
const {state, effects} = COMMANDS.calltree.arrow_right(s)
|
||||
const index = code.indexOf(substring)
|
||||
assert_equal(
|
||||
effects[0],
|
||||
{type: 'set_caret_position', args: [index]}
|
||||
)
|
||||
assert_equal(current_caret_position(state), index)
|
||||
if(is_assert_node_by_loc) {
|
||||
assert_equal(
|
||||
state.calltree_node_by_loc[''][index] == null,
|
||||
@@ -1903,10 +1891,8 @@ const y = x()`
|
||||
const {state: s3, effects} = COMMANDS.calltree.select_return_value(s2)
|
||||
assert_equal(s3.selection_state.result.value, 1)
|
||||
assert_equal(s3.selection_state.node.index, code.indexOf('x()'))
|
||||
assert_equal(
|
||||
effects,
|
||||
{type: 'set_caret_position', args: [code.indexOf('x()'), true]}
|
||||
)
|
||||
assert_equal(current_caret_position(s3), code.indexOf('x()'))
|
||||
assert_equal(effects, {type: 'set_focus'})
|
||||
}),
|
||||
|
||||
test('select_return_value expanded', () => {
|
||||
@@ -1921,10 +1907,8 @@ const y = x()`
|
||||
const {state: s3, effects} = COMMANDS.calltree.select_return_value(s2)
|
||||
assert_equal(s3.selection_state.result.value, 1)
|
||||
assert_equal(s3.selection_state.node.index, code.indexOf('1'))
|
||||
assert_equal(
|
||||
effects,
|
||||
{type: 'set_caret_position', args: [code.indexOf('1'), true]}
|
||||
)
|
||||
assert_equal(current_caret_position(s3), code.indexOf('1'))
|
||||
assert_equal(effects, {type: 'set_focus'})
|
||||
}),
|
||||
|
||||
test('select_return_value fn curly braces', () => {
|
||||
@@ -1939,10 +1923,8 @@ const y = x()`
|
||||
const {state: s3, effects} = COMMANDS.calltree.select_return_value(s2)
|
||||
assert_equal(s3.selection_state.result.value, 1)
|
||||
assert_equal(s3.selection_state.node.index, code.indexOf('1'))
|
||||
assert_equal(
|
||||
effects,
|
||||
{type: 'set_caret_position', args: [code.indexOf('1'), true]}
|
||||
)
|
||||
assert_equal(current_caret_position(s3), code.indexOf('1'))
|
||||
assert_equal(effects, {type: 'set_focus'})
|
||||
}),
|
||||
|
||||
test('select_return_value fn curly braces no return', () => {
|
||||
@@ -1956,10 +1938,8 @@ const y = x()`
|
||||
const s2 = COMMANDS.calltree.arrow_right(s2_0).state
|
||||
const {state: s3, effects} = COMMANDS.calltree.select_return_value(s2)
|
||||
assert_equal(s3.selection_state, null)
|
||||
assert_equal(
|
||||
effects,
|
||||
{type: 'set_caret_position', args: [code.indexOf('{'), true]}
|
||||
)
|
||||
assert_equal(current_caret_position(s3), code.indexOf('{'))
|
||||
assert_equal(effects, {type: 'set_focus'})
|
||||
}),
|
||||
|
||||
test('select_return_value native', () => {
|
||||
@@ -1983,10 +1963,8 @@ const y = x()`
|
||||
const s2 = COMMANDS.calltree.arrow_right(s1).state
|
||||
const s3 = COMMANDS.calltree.select_arguments(s2)
|
||||
assert_equal(s3.state.selection_state.result, {ok: true, value: [1]})
|
||||
assert_equal(
|
||||
s3.effects,
|
||||
{type: 'set_caret_position', args: [code.indexOf('(1)'), true]}
|
||||
)
|
||||
assert_equal(current_caret_position(s3.state), code.indexOf('(1)'))
|
||||
assert_equal(s3.effects, {type: 'set_focus'})
|
||||
}),
|
||||
|
||||
test('select_arguments expanded', () => {
|
||||
@@ -2001,10 +1979,8 @@ const y = x()`
|
||||
const s2 = COMMANDS.calltree.arrow_right(s2_0).state
|
||||
const s3 = COMMANDS.calltree.select_arguments(s2)
|
||||
assert_equal(s3.state.selection_state.result, {ok: true, value: {a: 1}})
|
||||
assert_equal(
|
||||
s3.effects,
|
||||
{type: 'set_caret_position', args: [code.indexOf('(a)'), true]}
|
||||
)
|
||||
assert_equal(current_caret_position(s3.state), code.indexOf('(a)'))
|
||||
assert_equal(s3.effects, {type: 'set_focus'})
|
||||
}),
|
||||
|
||||
test('move_cursor arguments', () => {
|
||||
@@ -2370,10 +2346,7 @@ const y = x()`
|
||||
const {state, effects} = COMMANDS.calltree.navigate_logs_position(i, 0)
|
||||
assert_equal(state.logs.log_position, 0)
|
||||
assert_equal(state.selection_state.result.value, [10])
|
||||
assert_equal(
|
||||
effects,
|
||||
{type: 'set_caret_position', args: [code.indexOf('(x)'), false]}
|
||||
)
|
||||
assert_equal(current_caret_position(state), code.indexOf('(x)'))
|
||||
}),
|
||||
|
||||
test('deferred calls', () => {
|
||||
|
||||
Reference in New Issue
Block a user