Exit state at end of line in ace editor syntax highlighter - syntax-highlighting

I'm writing a syntax highlighter for Ace Editor, and I'm having trouble correctly lexing function calls in this language. Function calls have two basic forms:
With parentheses:
function(foo, "bar")
With colons:
function: foo, "bar"
I can detect both forms, but once I go into the state of a colon-style function call, I have trouble getting back out of that state (which messes up the following lines). In particular, this problem exists when the function call ends with a string.
Below I've made a smaller version of the highlighter, that only focuses on this problem. The structure might seem overly complex, but bear in mind that this is part of a larger lexer, which I think warrants the complexity.
You can try it out in the mode creator with the following snippet, in which the third line does not get properly highlighted.
function(a, "bar")
function: a, "bar"
function("bar", a)
function: "bar", a
function("bar")
And here's the syntax definition:
define(function(require, exports, module) {
"use strict";
var oop = require("../lib/oop");
var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
var MyHighlightRules = function() {
var functions = [ "function" ];
this.$rules = {
"start" : [
{
token : 'keyword',
regex : '\\b(?:' + functions.join('|') + ')(?=\\s*[:(])',
push : [
{ include : 'function' },
]
}
],
// A function call
'function' : [
{
token : 'text',
regex : /(?:[:(])/,
push : [
{ include : 'comma_list' },
]
}, {
token : 'keyword',
regex : /(?:\)|(?=$))/,
next : 'pop'
}
],
// A series of arguments, separated by commas
'comma_list' : [
{
token : 'text',
regex : /\s+/,
}, {
token : 'string',
regex : /"/,
next : 'string',
}, {
include : "variable_name"
}
],
'variable-name' : [
{
token : 'keyword',
regex : /[a-z][a-zA-Z0-9_.]*/,
// This makes no difference
next : 'pop'
},
],
'string': [
{
token : 'string.quoted',
regex : /"/,
next : 'pop'
},
{ defaultToken : 'string.quoted' }
],
};
this.normalizeRules();
};
oop.inherits(MyHighlightRules, TextHighlightRules);
exports.MyHighlightRules = MyHighlightRules;
});
In specific: the /(?:\)|(?=$))/ in function seems to match only if the previous state was not a string. How can I get it to match regardless, so my lexer exists the function call even with colon-style function calls?
To confound things even more, if I change the regex to /(?:|(?=$))/ it highlights all the lines correctly, even though I can't understand why. What's going on here?

The main problem is that at the end of line ace allows only one state transition https://github.com/ajaxorg/ace/blob/master/lib/ace/tokenizer.js#L317. So after matching " at the end of line and switching to function state, it won't call regexp again so $ won't match anything. You probably can report this issue on github.
second issue is variable_name variable-name typo in your code.
Here's a modified version of your highlighter, which uses ^ in addition to $ to get highlighting similar to what you wanted.
define(function(require, exports, module) {
"use strict";
var oop = require("../lib/oop");
var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
var MyHighlightRules = function() {
var functions = [ "function" ];
this.$rules = {
"start" : [
{
token : 'keyword',
regex : '\\b(?:' + functions.join('|') + ')(?=\\s*[:(])',
push : [
{ include : 'function' },
]
}
],
// A function call
'function' : [
{
token : 'paren',
regex : /(?:[:(])/,
},
{
token : 'paren',
regex : /(?:\)|$|^)/,
next : 'pop'
},
{ include : 'commaList' },
],
// A series of arguments, separated by commas
'commaList' : [
{
token : 'text',
regex : /\s+/,
}, {
token : 'string.start',
regex : /"/,
push : 'string',
}, {
include : "variableName"
}
],
'variableName' : [
{
token : 'variable.parameter',
regex : /[a-z][a-zA-Z0-9_.]*/
},
],
'string': [
{
token : 'string.end',
regex : /"/,
next : 'pop'
},
{ defaultToken : 'string.quoted' }
],
};
this.normalizeRules();
};
oop.inherits(MyHighlightRules, TextHighlightRules);
exports.MyHighlightRules = MyHighlightRules;
});

Related

missing type in composite literal in golang/mongodb aggregate query

I want to write mongo query in golang. my mongo query is -
aggregate([
{$match: {$and :
[
{"stream" : "CS"},
{"semester" : "sem3"},
{"section" : "A"}
]
}},
{$unwind: '$atndnc'},
{ $group: { _id:{rollno: "$atndnc.rollno",attend:"$atndnc.attend"},count: { $sum: 1 }}},
{ $project:
{ _id: '$_id.rollno',
'attend' : '$_id.attend',
'count' : '$count'
}}
])
And my Go code is -
cond:=[]bson.M{
bson.M{"$match": bson.M{"$and ":[]interface{}{
bson.M{"stream" : srchobj.Stream},
bson.M{"semester" : srchobj.Semester},
bson.M{"section" : srchobj.Section},
bson.M{"college_id":srchobj.College_id},
bson.M{"date":bson.M{"$gt":srchobj.Startdate,"$lt":srchobj.Enddate}}}}},
bson.M{"$unwind": "$atndnc"},
bson.M{"$group":bson.M{"_id":{"rollno":bson.M{"$atndnc.rollno"},"attend":bson.M{"$atndnc.attend"}},"count":bson.M{"$sum":1}}},
bson.M{"$project":bson.M{"_id":"$_id.rollno","count":"$_id.count"}}}
but it give the error "missing type in composite literal" in
bson.M{"$group":bson.M{"_id":{"rollno":bson.M{"$atndnc.rollno"},"attend":bson.M{"$atndnc.attend"}},"count":bson.M{"$sum":1}}},
in this line.what should i do now?
You have a missing type declaration on a set of braces in your $group query:
{"rollno":bson.M{"$atndnc.rollno"},"attend":bson.M{"$atndnc.attend"}}
I would assume should be:
bson.M{"rollno":bson.M{"$atndnc.rollno"},"attend":bson.M{"$atndnc.attend":nil}}
there are also a few other initialization things like initializations with just a string key (remember, a bson.M is just an alias for map[string]interface{}
Thanks for your support.I got the desired output by doing this.
cond :=[]bson.M{
bson.M{"$match": bson.M{
"stream" : srchobj.Stream,
"semester" : srchobj.Semester,
"section" : srchobj.Section,
"college_id":srchobj.College_id,
"date":bson.M{
"$gt":srchobj.Startdate,
"$lt":srchobj.Enddate},
},
},
bson.M{"$unwind": "$atndnc"},
bson.M{"$group":bson.M{
"_id":bson.M{
"rollno":"$atndnc.rollno",
"attend":"$atndnc.attend",
"name":"$atndnc.name",
},
"count":bson.M{"$sum":1},
},
},
bson.M{"$project":bson.M{
"rollno":"$_id.rollno",
"name":"$_id.name",
"count":"$count",
"attend":"$_id.attend",
},
},
bson.M{"$sort":bson.M{"rollno":1}},
}

Extjs validate in separate files

I'm trying to validate fields in my form, but I keep getting an error message.
Here is my code:
Ext.define('ExtDoc.views.extfields.FieldsValidator',{
valEng: function(val) {
var engTest = /^[a-zA-Z0-9\s]+$/;
Ext.apply(Ext.form.field.VTypes, {
eng: function(val, field) {
return engTest.test(val);
},
engText: 'Write it in English Please',
// vtype Mask property: The keystroke filter mask
engMask: /[a-zA-Z0-9_\u0600-\u06FF\s]/i
});
}
});
And I define my field as follow:
{
"name": "tik_moed_chasifa",
"type": "ExtDoc.views.extfields.ExtDocTextField",
"label": "moed_hasifa",
"vtype": "eng",
"msgTarget": "under"
}
The first snippet is in a separate js file, and I have it in my fields js file as required.
When I start typing text in the text field, I keep seeing the following error msg in the explorer debugger:
"SCRIPT438: Object doesn't support property or method 'eng' "
What could it be? Have I declared something wrong?
You have defined your own class with a function valEng(val), but you don't instantiate it, neither do you call the function anywhere.
Furthermore, your function valEng(val) does not require a parameter, because you are not using that parameter anywhere.
It would be far easier and more readable, would you remove the Ext.define part and create the validators right where you need them. For instance if you need them inside an initComponent function:
initComponent:function() {
var me = this;
Ext.apply(Ext.form.field.VTypes, {
mobileNumber:function(val, field) {
var numeric = /^[0-9]+$/
if(!Ext.String.startsWith(val,'+')) return false;
if(!numeric.test(val.substring(1))) return false;
return true;
},
mobileNumberText:'This is not a valid mobile number'
});
Ext.apply(me,{
....
items: [{
xtype:'fieldcontainer',
items:[{
xtype: 'combobox',
vtype: 'mobileNumber',
Or, you could add to your Application.js, in the init method, if you need it quite often at different levels of your application:
Ext.define('MyApp.Application', {
extend: 'Ext.app.Application',
views: [
],
controllers: [
],
stores: [
],
init:function() {
Ext.apply(Ext.form.field.VTypes, {
mobileNumber:function(val, field) {
var numeric = /^[0-9]+$/
if(!Ext.String.startsWith(val,'+')) return false;
if(!numeric.test(val.substring(1))) return false;
return true;
},
mobileNumberText:'This is not a valid mobile number'
});
}

Complex array in Ruby

I need to create this structure in ruby
{
"list": {
"ownerList" : [ {
"owner" : "Nacho",
"list" : "MyList"
},
{
"owner" : "Nacho2",
"list" : "MyList2"
}
]
}
}
but I'm not sure how to create a multientry array in ruby. Any ideas?
my_hash = {
owner_list: [
{
owner: "Nacho",
list: "MyList"
},
{
owner: "Nacho",
list: "MyList"
},
]
}
This creates a hash with the data you want. You can then very easily transform it to a json if you like and make operations over it.

how to use mongodb query option in monk nodejs

I have a collection name projects and I am trying to retrieve everything except its url like this query
db.projects.find({name:"arisha"},{url:0}).pretty()
This query is working perfectly and returning everything except url but my question is how to achieve this in
Node module for MongoDB name monk.
I am using this code but its not working and returning every field:
var projs = db.get('projects');
projs.find({creator : req.session.user._id},{url:0}, function (err,data) {
console.log(data);
if(!err) {
res.locals.projs = data;
console.log(data);
res.render("projects.ejs",{title: "Projects | Bridge"});
}
});
I did not get where the problem is, please help and thanks in advance :)
Sample document:
{
"name" : "arisha",
"date" : {
"day" : 18,
"month" : 4,
"year" : 2015
},
"creator" : "552edb6f8617322203701ad1",
"url" : "EyjPdYoW",
"members" : [
"552edb6f8617322203701ad1"
],
"_id" : ObjectId("5532994ba8ffdca31258bd1a")
}
To exclude the url field in monk, try the following syntax:
var db = require('monk')('localhost/mydb');
var projs = db.get('projects');
projs.find({ creator : req.session.user._id }, "-url", function (err, data) {
// exclude url field
});
EDIT:
To exclude multiple fields, use the following projection syntax:
projs.find({ creator : req.session.user._id }, { fields: { url: 0, creator: 0 } }, function(err, data) {
// exclude the fields url and creator
});
Alternatively (as you had discovered), you could also do:
projs.find({ creator : req.session.user._id }, "-url -creator", function (err, data) {
// exclude url and creator fields
});

Query nested items containing all words

I have an index in elastic search that contains simple nested items, defined this way:
'index' : 'items',
'body' : {
'name' : {'type' : 'string'},
'steps' : {
'type' : 'nested',
'text' : {'type' : 'string'},
}
}
Each step is a line in the object definition. Let's consider I have the four following objects:
obj1:
foo
obj2:
bar
obj3:
foo bar
obj4:
foo
bar
I want to be able to search objects that have a line containing all words in the query. So If I query with 'foo bar', only 'obj3' will appear in the result.
My current query is has follows:
'index : 'items',
'body' : {
'query' : {
'match' : {
"steps.text": {
'query' : 'foo bar',
'operator' : 'and'
}
}
}
This query almost works (it filters out obj1 and obj2 as they only contain one of the word) but obj4 still appears.
So is there a way to tell elastic search "at least one step matches all the words" ?
Thanks in advance,
Vincent
Finally solve the issue :)
The query should have been:
{
nested: {
path: 'steps',
query: {
match: {
text: {
query: 'foo bar',
operator: 'AND'
}
}
}
}
}
This way it only finds items where one step contains 'foo' and 'bar'.

Resources