Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
erp5
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Ekaterina
erp5
Commits
fc4a7ff1
Commit
fc4a7ff1
authored
Nov 05, 2019
by
Jérome Perrin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
monaco_editor: also enable jedi for codelens ( WIP: ZMI only )
parent
9e56f95d
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
57 additions
and
160 deletions
+57
-160
bt5/erp5_monaco_editor/ExtensionTemplateItem/portal_components/extension.erp5.Jedi.py
...sionTemplateItem/portal_components/extension.erp5.Jedi.py
+9
-154
bt5/erp5_monaco_editor/ExtensionTemplateItem/portal_components/extension.erp5.Jedi.xml
...ionTemplateItem/portal_components/extension.erp5.Jedi.xml
+6
-5
bt5/erp5_monaco_editor/SkinTemplateItem/portal_skins/erp5_monaco_editor/monaco_editor_support.zpt
...portal_skins/erp5_monaco_editor/monaco_editor_support.zpt
+42
-1
No files found.
bt5/erp5_monaco_editor/ExtensionTemplateItem/portal_components/extension.erp5.Jedi.py
View file @
fc4a7ff1
...
...
@@ -3,13 +3,11 @@ import json
import
sys
from
threading
import
RLock
import
logging
import
inspect
logger
=
logging
.
getLogger
(
"erp5.extension.Jedi"
)
import
os
import
jedi
import
zope.dottedname.resolve
import
time
last_reload_time
=
time
.
time
()
...
...
@@ -22,11 +20,11 @@ jedi.settings.call_signatures_validity = 30
# rdiff-backup seem to trigger a bug, but it's generally super slow and not correct for us.
try
:
# in jedi 0.15.1 it's here
from
jedi.evaluate
import
sys_path
as
jedi_inference_sys_path
# pylint: disable=import-error
from
jedi.evaluate
import
sys_path
as
jedi_inference_sys_path
# pylint: disable=import-error,unused-import,no-name-in-module
except
ImportError
:
# but it's beeing moved. Next release will be here
# https://github.com/davidhalter/jedi/commit/3b4f2924648eafb9660caac9030b20beb50a83bb
from
jedi.inference
import
sys_path
as
jedi_inference_sys_path
# pylint: disable=import-error
from
jedi.inference
import
sys_path
as
jedi_inference_sys_path
# pylint: disable=import-error
,unused-import,no-name-in-module
_
=
jedi_inference_sys_path
.
discover_buildout_paths
# make sure it's here
...
...
@@ -40,7 +38,7 @@ jedi_api_project.discover_buildout_paths = dont_discover_buildout_paths
try
:
# for local types annotations in this component
from
erp5.portal_type
import
ERP5Site
# pylint: disable=unused-import
from
erp5.portal_type
import
ERP5Site
# pylint: disable=unused-import
,no-name-in-module
except
ImportError
:
pass
...
...
@@ -77,14 +75,6 @@ def executeJediXXX(callback, context, arguments):
#import pdb; pdb.set_trace()
return
val
.
gather_annotation_classes
().
filter
(
filter_func
)
# XXX
if
str
(
val
).
count
(
'<LazyGenericClass:'
)
==
1
:
logger
.
info
(
"I don't know ... %s because %s in %s"
,
"{}@"
.
format
(
class_from_portal_type
)
in
str
(
val
),
"{}@"
.
format
(
class_from_portal_type
),
val
)
return
"{}@"
.
format
(
class_from_portal_type
)
in
str
(
val
)
logger
.
info
(
"not found in %s"
,
val
)
return
False
...
...
@@ -199,145 +189,6 @@ def makeERP5Plugin():
# methods returning List of portal types
# methods returning List of Brain of portal types
return
call
()
return
wrapper
def
not_used_import_module
(
self
,
callback
):
# TODO: remove, not used
"""
Handle ERP5 dynamic modules import.
"""
from
jedi.evaluate.context
import
ModuleContext
,
StubModuleContext
logger
.
info
(
"JediERP5Plugin registering import_module"
)
def
wrapper
(
evaluator
,
import_names
,
module_context
,
*
args
,
**
kwargs
):
if
len
(
import_names
)
>
1
and
import_names
[:
2
]
in
(
(
'erp5'
,
'portal_type'
),
(
'erp5'
,
'accessor_holder'
),
(
'erp5'
,
'skins_tool'
),
(
'erp5'
,
'component'
)):
try
:
if
1
:
erp5_code
=
'''
from . import portal_type
from . import skins_tool
from . import accessor_holder
from . import component
'''
portal
=
self
.
_getPortalObject
()
module_to_component_portal_type_mapping
=
{
'test'
:
'Test Component'
,
'document'
:
'Document Component'
,
'extension'
:
'Extension Component'
,
'tool'
:
'Tool Component'
,
'module'
:
'Module Component'
,
'interface'
:
'Interface Component'
,
}
if
import_names
==
(
'erp5'
,
'portal_type'
):
source_code
=
self
.
_cache
.
get
(
'portal_type'
)
if
not
source_code
:
source_code
=
portal
.
portal_types
.
TypesTool_getStub
()
self
.
_cache
[
'portal_type'
]
=
source_code
source_path
=
"erp5/portal_type.pyi"
elif
import_names
==
(
'erp5'
,
'accessor_holder'
):
source_code
=
self
.
_cache
.
get
(
'accessor_holder'
)
if
not
source_code
:
source_code
=
portal
.
portal_types
.
PropertySheetTool_getStub
()
self
.
_cache
[
'accessor_holder'
]
=
source_code
source_path
=
"erp5/accessor_holder.pyi"
elif
import_names
==
(
'erp5'
,
'skins_tool'
):
source_code
=
self
.
_cache
.
get
(
'skins_tool'
)
if
not
source_code
:
source_code
=
portal
.
portal_skins
.
SkinsTool_getStub
()
self
.
_cache
[
'skins_tool'
]
=
source_code
source_path
=
"erp5/skins_tool.pyi"
elif
import_names
[
1
]
in
(
'portal_types'
,
'accessor_holder'
,
'skins_tool'
):
# fallback
return
callback
(
evaluator
,
import_names
,
module_context
,
*
args
,
**
kwargs
)
else
:
# if import_name[-1] == 'component':
dotted_name
=
'.'
.
join
(
import_names
)
logger
.
info
(
'looking up code for %s'
,
dotted_name
)
# we don't have source for some modules
if
dotted_name
==
'erp5.component'
:
source_code
=
textwrap
.
dedent
(
'''
\
from . import document
from . import test
from . import extension
from . import tool
from . import interface
from . import module
'''
)
elif
len
(
import_names
)
==
3
and
import_names
[:
2
]
==
(
'erp5'
,
'component'
)
and
import_names
[
2
]
in
module_to_component_portal_type_mapping
:
line_list
=
[]
for
brain
in
portal
.
portal_catalog
.
searchResults
(
portal_type
=
module_to_component_portal_type_mapping
[
import_names
[
2
]],
validation_state
=
'validated'
,
select_dict
=
{
'reference'
:
None
}):
line_list
.
append
(
'from . import {}'
.
format
(
brain
.
reference
))
source_code
=
'
\
n
'
.
join
(
line_list
)
else
:
source_code
=
inspect
.
getsource
(
zope
.
dottedname
.
resolve
.
resolve
(
dotted_name
))
source_path
=
"{}.pyi"
.
format
(
'/'
.
join
(
import_names
))
logger
.
info
(
'got code for %s'
,
source_path
)
# logger.error('unsupported import %s', import_names)
# raise NotImplementedError()
#logger.info('got code for %s', source_path)
source
=
StringIO
(
source_code
)
# XXX make this StringIO look like a jedi FileIO
source
.
get_last_modified
=
lambda
:
last_reload_time
# os.path.getmtime(file_path) # TODO
source
.
path
=
source_path
source
.
get_parent_folder
=
lambda
:
None
# TODO bug with using StringIO
# AttributeError: StringIO instance has no attribute 'get_parent_folder'
# email = pers.newContent(portal_type='Email')
module
=
evaluator
.
parse
(
file_io
=
source
,
cache
=
True
,
use_latest_grammar
=
True
)
# XXX needed ?
erp5_source
=
StringIO
(
erp5_code
)
erp5_source
.
path
=
"erp5.py"
erp5_source
.
get_last_modified
=
lambda
:
13
erp5_module
=
evaluator
.
parse
(
file_io
=
erp5_source
,
cache
=
True
,
use_latest_grammar
=
True
)
non_stub_context
=
ModuleContext
(
evaluator
,
erp5_module
,
file_io
=
erp5_source
,
string_names
=
None
,
code_lines
=
get_cached_code_lines
(
evaluator
.
latest_grammar
,
erp5_source
.
path
),
is_package
=
True
)
non_stub_context
.
is_builtins_module
=
lambda
:
False
parent_context
=
StubModuleContext
(
ContextSet
([
non_stub_context
]),
evaluator
,
module
,
file_io
=
source
,
string_names
=
None
,
#('erp5', 'portal_type'),
code_lines
=
get_cached_code_lines
(
evaluator
.
latest_grammar
,
source
.
path
),
# is_package=True
)
parent_context
.
is_builtins_module
=
lambda
:
False
#logger.info('got context %s', parent_context)
#import pdb; pdb.set_trace()
return
ContextSet
([
non_stub_context
,
parent_context
])
except
Exception
:
logger
.
exception
(
"merde"
)
return
callback
(
evaluator
,
import_names
,
module_context
,
*
args
,
**
kwargs
)
logger
.
info
(
'returning %s'
,
wrapper
)
return
wrapper
return
JediERP5Plugin
()
...
...
@@ -530,6 +381,10 @@ def ERP5Site_getPythonSourceCodeCompletionList(self, data, REQUEST=None):
"jedi got %d completions in %.2fs"
,
len
(
completions
),
(
time
.
time
()
-
start
))
if
data
.
get
(
'xxx_hover'
):
completions
=
''
# XXX this is not "completions" ...
for
definition
in
script
.
goto_definitions
():
completions
=
definition
.
docstring
()
if
REQUEST
is
not
None
:
REQUEST
.
RESPONSE
.
setHeader
(
'content-type'
,
'application/json'
)
return
json
.
dumps
(
completions
)
...
...
bt5/erp5_monaco_editor/ExtensionTemplateItem/portal_components/extension.erp5.Jedi.xml
View file @
fc4a7ff1
...
...
@@ -46,11 +46,12 @@
<key>
<string>
text_content_warning_message
</string>
</key>
<value>
<tuple>
<string>
W: 58, 2: Reimport \'ContextSet\' (imported line 49) (reimported)
</string>
<string>
W: 81, 8: Unreachable code (unreachable)
</string>
<string>
W: 76, 8: Unused variable \'annotation_classes\' (unused-variable)
</string>
<string>
W:158, 8: Unreachable code (unreachable)
</string>
<string>
W:186, 16: Unused variable \'filtered\' (unused-variable)
</string>
<string>
W: 61, 2: Reimport \'ContextSet\' (imported line 52) (reimported)
</string>
<string>
W: 79, 8: Unused variable \'annotation_classes\' (unused-variable)
</string>
<string>
W:156, 8: Unreachable code (unreachable)
</string>
<string>
W:184, 16: Unused variable \'filtered\' (unused-variable)
</string>
<string>
W:132, 2: Unused variable \'get_cached_code_lines\' (unused-variable)
</string>
<string>
W:133, 2: Unused variable \'StringIO\' (unused-variable)
</string>
</tuple>
</value>
</item>
...
...
bt5/erp5_monaco_editor/SkinTemplateItem/portal_skins/erp5_monaco_editor/monaco_editor_support.zpt
View file @
fc4a7ff1
...
...
@@ -349,7 +349,48 @@ $script.onload = function() {
/* ignore aborted requests */
});
}
});
});
monaco.languages.registerHoverProvider('python', {
provideHover: function (model, position, token) {
const controller = new AbortController();
token.onCancellationRequested(() => {controller.abort()})
const data = new FormData();
const complete_parameters = {
code: model.getValue(),
position: {line: position.lineNumber, column: position.column}
};
// ZMI python scripts pass extra parameters to linter
if (bound_names) {
complete_parameters["script_name"] = script_name;
complete_parameters["bound_names"] = JSON.parse(bound_names);
complete_parameters["params"] = document.querySelector(
'input[name="params"]'
).value;
}
complete_parameters['xxx_hover'] = true;
data.append("data", JSON.stringify(complete_parameters));
return fetch(portal_url + "/ERP5Site_getPythonSourceCodeCompletionList", {
method: "POST",
body: data,
signal: controller.signal
})
.then(response => response.json())
.then(data => {
return {
range: new monaco.Range(position.lineNumber, position.column, position.lineNumber, 0),
contents: [
{ value: data }, // XXX
]
}
}, e => {
if (!e instanceof DOMException /* AbortError */ ) {
throw e;
}
/* ignore aborted requests */
});
}
});
if (mode === "python") {
// Perform a first check when loading document.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment