Can you highlight a character after a certain length in sublime text? - sublimetext2

In VIM it is possible to highlight a character only if the line goes over a certain length, for example:
Can this be done in Sublime Text 2 or 3? I know there's a setting to display rulers but I find them a bit distracting sometimes.

javiervd
Can this be done in Sublime Text 2 or 3?
Save the following script #:
/Packages/Highlight Long Lines/highlight_long_lines.py
import sublime, sublime_plugin
class highlight_long_lines( sublime_plugin.EventListener ):
def on_modified_async( self, view ):
#▒▒▒▒▒▒▒▒ Settings ▒▒▒▒▒▒▒▒#
maxLength = 80
scope = "Invalid"
firstCharacter_Only = False
view.erase_regions( "LongLines" )
indentationSize = view.settings().get( "tab_size" )
indentation_IsSpace = view.settings().get( "translate_tabs_to_spaces" )
document = sublime.Region( 0, view.size() )
lineRegions = view.lines( document )
invalidRegions = []
for region in lineRegions:
text = view.substr( region )
text_WithoutTabs = text.expandtabs( indentationSize )
if text_WithoutTabs.isspace():
tabOffset = 0
else:
tabCount = text.count( " " )
tabDifference = len( text_WithoutTabs ) - len( text )
tabOffset = tabDifference
lineLength = ( region.end() - region.begin() ) - tabOffset
if lineLength > maxLength:
highlightStart = region.begin() + ( maxLength - tabOffset )
if firstCharacter_Only == True:
highlightEnd = highlightStart + 1
else:
highlightEnd = region.end()
invalidRegion = sublime.Region( highlightStart, highlightEnd )
invalidRegions.append( invalidRegion )
if len( invalidRegions ) > 0:
view.add_regions( "LongLines", invalidRegions, scope )
Variable Settings:
maxLength affects the length that lines will highlight after.
scope affects the color of the highlighted regions.
You can use any scope from your active .tmTheme file ( color scheme ).
firstCharacter_Only affects the extent of the highlighted regions.
If set to True, only the character at the 81st position will be highlighted.
If set to False, all characters after the 80th position will be highlighted.

You could just search for this regular expression:
(?<=.{80}).+
It would be navigable and on-demand.

You can extend(copy-rename and use) the syntax highlight and add a rule with this specific case!
you can add a regex similar to this:
<key>charAt</key>
<dict>
<key>patterns</key>
<array>
<dict>
<key>match</key>
<string>(?<=^.{21})(.)</string>
<key>name</key>
<string>invalid.illegal.bad-comments-or-CDATA.html</string>
</dict>
</array>
</dict>
where 21 is the position to highlight

Related

Plotly Express: Prevent bars from stacking when Y-axis catgories have the same name

I'm new to plotly.
Working with:
Ubuntu 20.04
Python 3.8.10
plotly==5.10.0
I'm doing a comparative graph using a horizontal bar chart. Different instruments measuring the same chemical compounds. I want to be able to do an at-a-glance, head-to-head comparison if the measured value amongst all machines.
The problem is; if the compound has the same name amongst the different instruments - Plotly stacks the data bars into a single bar with segment markers. I very much want each bar to appear individually. Is there a way to prevent Plotly Express from automatically stacking the common bars??
Examples:
CODE
gobardata = []
for blended_name in _df[:20].blended_name: # should always be unique
##################################
# Unaltered compound names
compound_names = [str(c) for c in _df[_df.blended_name == blended_name]["injcompound_name"].tolist()]
# Random number added to end of compound_names to make every string unique
# compound_names = ["{} ({})".format(str(c),random.randint(0, 1000)) for c in _df[_df.blended_name == blended_name]["injcompound_name"].tolist()]
##################################
deltas = _df[_df.blended_name == blended_name]["delta_rettime"].to_list()
gobardata.append(
go.Bar(
name = blended_name,
x = deltas,
y = compound_names,
orientation='h',
))
fig = go.Figure(data = gobardata)
fig.update_traces(width=1)
fig.update_layout(
bargap=1,
bargroupgap=.1,
xaxis_title="Delta Retention Time (Expected - actual)",
yaxis_title="Instrument name(Injection ID)"
)
fig.show()
What I'm getting (Using actual, but repeated, compound names)
What I want (Adding random text to each compound name to make it unique)
OK. Figured it out. This is probably pretty klugy, but it consistently works.
Basically...
Use go.FigureWidget...
...with make_subplots having a common x-axis...
...controlling the height of each subplot based on number of bars.
Every bar in each subplot is added as an individual trace...
...using a dictionary matching bar name to a common color.
The y-axis labels for each subplot is a list containing the machine name as [0], and then blank placeholders ('') so the length of the y-axis list matches the number of bars.
And manually manipulating the legend so each bar name appears only once.
# Get lists of total data
all_compounds = list(_df.injcompound_name.unique())
blended_names = list(_df.blended_name.unique())
#################################################################
# The heights of each subplot have to be set when fig is created.
# fig has to be created before adding traces.
# So, create a list of dfs, and use these to calculate the subplot heights
dfs = []
subplot_height_multiplier = 20
subplot_heights = []
for blended_name in blended_names:
df = _df[(_df.blended_name == blended_name)]#[["delta_rettime", "injcompound_name"]]
dfs.append(df)
subplot_heights.append(df.shape[0] * subplot_height_multiplier)
chart_height = sum(subplot_heights) # Prep for the height of the overall chart.
chart_width = 1000
# Make the figure
fig = make_subplots(
rows=len(blended_names),
cols=1,
row_heights = subplot_heights,
shared_xaxes=True,
)
# Create the color dictionary to match a color to each compound
_CSS_color = CSS_chart_color_list()
colors = {}
for compound in all_compounds:
try: colors[compound] = _CSS_color.pop()
except IndexError:
# Probably ran out of colors, so just reuse
_CSS_color = CSS_color.copy()
colors[compound] = _CSS_color.pop()
rowcount = 1
for df in dfs:
# Add bars individually to each subplot
bars = []
for label, labeldf in df.groupby('injcompound_name'):
fig.add_trace(
go.Bar(x = labeldf.delta_rettime,
y = [labeldf.blended_name.iloc[0]]+[""]*(len(labeldf.delta_rettime)-1),
name = label,
marker = {'color': colors[label]},
orientation = 'h',
),
row=rowcount,
col=1,
)
rowcount += 1
# Set figure to FigureWidget
fig = go.FigureWidget(fig)
# Adding individual traces creates redundancies in the legend.
# This removes redundancies from the legend
names = set()
fig.for_each_trace(
lambda trace:
trace.update(showlegend=False)
if (trace.name in names) else names.add(trace.name))
fig.update_layout(
height=chart_height,
width=chart_width,
title_text="∆ of observed RT to expected RT",
showlegend = True,
)
fig.show()

get_coherence : C_V method gets an error but U_Mass works

I'm using the following code to check the coherence value. The problem is code below works well when I change the coherence type into "u_mass", but if I want to compute "c_v", an Index error occure.
Previous text process:
# Remove Stopwords, Form Bigrams, Trigrams and Lemmatization
def process_words(texts, stop_words=stop_words, allowed_postags=['NOUN', 'ADJ', 'VERB', 'ADV']):
texts = [[word for word in simple_preprocess(str(doc)) if word not in stop_words] for doc in texts]
texts = [bigram_mod[doc] for doc in texts]
texts = [trigram_mod[bigram_mod[doc]] for doc in texts]
texts_out = []
nlp = spacy.load("en_core_web_sm", disable=['parser', 'ner'])
for sent in texts:
doc = nlp(" ".join(sent))
texts_out.append([token.lemma_ for token in doc if token.pos_ in allowed_postags])
# remove stopwords once more after lemmatization
texts_out = [[word for word in simple_preprocess(str(doc)) if word not in stop_words] for doc in texts_out]
## Remove numbers, but not words that contain numbers.
texts_out = [[word for word in simple_preprocess(str(doc)) if not word.isdigit()] for doc in texts_out]
## Remove words that are only one character.
texts_out = [[word for word in simple_preprocess(str(doc)) if len(word) > 3] for doc in texts_out]
return texts_out
data_ready = process_words(data_words)
# Create Dictionary
id2word = corpora.Dictionary(data_ready)
#dictionary.filter_extremes(no_below=10, no_above=0.2) #filter out tokens
# Create Corpus: Term Document Frequency
corpus = [id2word.doc2bow(text) for text in data_ready]
# View:the produced corpus shown above is a mapping of (word_id, word_frequency).
print(corpus[:1])
print('Number of unique tokens: %d' % len(id2word))
print('Number of documents: %d' % len(corpus))
The output is :
[[(0, 1), (1, 1), (2, 1), (3, 1)]]
Number of unique tokens: 6558
Number of documents: 23141
Now I set a base model:
## set a base model
num_topics = 5
chunksize = 100
passes = 10
iterations = 100
eval_every = 1
lda_model = LdaModel(corpus=corpus,id2word=id2word, chunksize=chunksize, \
alpha='auto', eta='auto', \
iterations=iterations, num_topics=num_topics, \
passes=passes, eval_every=eval_every)
The last step is where the problem occurs:
# Compute Coherence Score
coherence_model_lda = CoherenceModel(model=lda_model, texts=data_ready, dictionary=id2word, coherence="c_v")
coherence_lda = coherence_model_lda.get_coherence()
print('\nCoherence Score: ', coherence_lda)
Here is the error:
IndexError: index 0 is out of bounds for axis 0 with size 0
If I change coherence into 'u_mass', however, the code ablove can compute successfully. I don't understand why and how to fix it?
!pip install gensim==4.1.0
It seems that downgrade solves everything.
Just in case anyone else runs into the same issue.
Apparently the error described here persist in gensim 4.2.0. Downgrading to 4.1.0 worked well for me.

Expand selection to custom line

I am wondering if there is a out of the box way, or a plugin that can achieve the following behaviour in SublimeText3.
I would like to put the caret at a certain line. And then select all the text until another line number. The amount of lines should be variable.
For example put the caret on 10 and then expand selection to line 21 or line 104.
I hate having to hold down key or use the mouse for this action.
I wrote a simple plugin that allows you to enter a line to select until via an input_panel:
Features:
works bidirectionally
respects the current selection
only executes if there is a single selection
Setup Info:
# GitHub
Code:
import sublime, sublime_plugin
class SelectToLineCommand( sublime_plugin.TextCommand ):
def run( self, edit ):
window = self.view.window()
selections = self.view.sel()
if len( selections ) != 1:
return
self.currentSelection = selections[0]
if self.currentSelection.a > self.currentSelection.b:
self.currentSelection = sublime.Region( self.currentSelection.b, self.currentSelection.a )
window.show_input_panel( "Select To Line Number", "", self.get_LineNumber, None, None )
def get_LineNumber( self, userInput ):
lineToRow_Offset = 1
row = int( userInput ) - lineToRow_Offset
selectionEnd_Row = self.view.text_point( row, 0 )
currentSelection = self.currentSelection
if selectionEnd_Row >= currentSelection.b:
selectionStart = currentSelection.a
selectionEnd = self.view.line( selectionEnd_Row ).b
elif selectionEnd_Row < currentSelection.a:
selectionStart = currentSelection.b
selectionEnd = self.view.line( selectionEnd_Row ).a
newSelection = sublime.Region( selectionStart, selectionEnd )
self.view.selection.clear()
self.view.selection.add( newSelection )

Object of type 'closure' is not subsettable - R

I am using R to extract tweets and analyse their sentiment, however when I get to the lines below I get an error saying "Object of type 'closure' is not subsettable"
scores$drink = factor(rep(c("east"), nd))
scores$very.pos = as.numeric(scores$score >= 2)
scores$very.neg = as.numeric(scores$score <= -2)
Full code pasted below
load("twitCred.Rdata")
east_tweets <- filterStream("tweetselnd.json", locations = c(-0.10444, 51.408699, 0.33403, 51.64661),timeout = 120, oauth = twitCred)
tweets.df <- parseTweets("tweetselnd.json", verbose = FALSE)
##function score.sentiment
score.sentiment = function(sentences, pos.words, neg.words, .progress='none')
{
# Parameters
# sentences: vector of text to score
# pos.words: vector of words of postive sentiment
# neg.words: vector of words of negative sentiment
# .progress: passed to laply() to control of progress bar
scores = laply(sentences,
function(sentence, pos.words, neg.words)
{
# remove punctuation
sentence = gsub("[[:punct:]]", "", sentence)
# remove control characters
sentence = gsub("[[:cntrl:]]", "", sentence)
# remove digits?
sentence = gsub('\\d+', '', sentence)
# define error handling function when trying tolower
tryTolower = function(x)
{
# create missing value
y = NA
# tryCatch error
try_error = tryCatch(tolower(x), error=function(e) e)
# if not an error
if (!inherits(try_error, "error"))
y = tolower(x)
# result
return(y)
}
# use tryTolower with sapply
sentence = sapply(sentence, tryTolower)
# split sentence into words with str_split (stringr package)
word.list = str_split(sentence, "\\s+")
words = unlist(word.list)
# compare words to the dictionaries of positive & negative terms
pos.matches = match(words, pos.words)
neg.matches = match(words, neg.words)
# get the position of the matched term or NA
# we just want a TRUE/FALSE
pos.matches = !is.na(pos.matches)
neg.matches = !is.na(neg.matches)
# final score
score = sum(pos.matches) - sum(neg.matches)
return(score)
}, pos.words, neg.words, .progress=.progress )
# data frame with scores for each sentence
scores.df = data.frame(text=sentences, score=scores)
return(scores.df)
}
pos = readLines(file.choose())
neg = readLines(file.choose())
east_text = sapply(east_tweets, function(x) x$getText())
scores = score.sentiment(tweetseldn.json, pos, neg, .progress='text')
scores()$drink = factor(rep(c("east"), nd))
scores()$very.pos = as.numeric(scores()$score >= 2)
scores$very.neg = as.numeric(scores$score <= -2)
# how many very positives and very negatives
numpos = sum(scores$very.pos)
numneg = sum(scores$very.neg)
# global score
global_score = round( 100 * numpos / (numpos + numneg) )
If anyone could help with as to why I'm getting this error it will be much appreciated. Also I've seen other answeres about adding '()' when referring to the variable 'scores' such as scores()$.... but it hasn't worked for me. Thank you.
The changes below got rid of the error:
x <- scores
x$drink = factor(rep(c("east"), nd))
x$very.pos = as.numeric(x$score >= 2)
x$very.neg = as.numeric(x$score <= -2)

Embedded bitmaps in svg not showing

I have embedded two images in this svg, but the images doesn't show up. What's wrong with what I did?
http://dl.dropbox.com/u/5363697/whirl_browserready.svg
MORE INFORMATION:
I do the image embedding with the following code, in case it helps:
xpath_expr = '//*[#{1}="{0}"]'.format(layername, INKSCAPE_XPATH('label') )
layer_el = svg_doc.xpath( xpath_expr,
namespaces = NE_NS_MAP
)[0]
obj_id = layer_el.attrib['id']
# Keep it safe somewhere, now export that little element as an image
output_el = tempfile.NamedTemporaryFile(
suffix='_temp.svg' )
cmd_line = [
'inkscape',
'--export-id=' + obj_id,
'--export-id-only',
'--export-area-drawing',
'--export-dpi=90', # Change here if required
'--export-png=' + output_el.name,
REL_SIMPLIFIED_LOCATION
]
subprocess.check_call( cmd_line )
# Now load back the file, as a 'buffer'
whole_file = output_el.read()
assert len( whole_file ) > 0
bf = base64.b64encode( whole_file )
# Change that 'g' element by an 'image' element
g_element = etree.Element(SVG('image') )
g_element.attrib[XLINK('href')] = "data:image/png;base64," + bf
(width, height) = get_object_size( obj_id )
print(width,height)
g_element.attrib[SVG('width')] = str( width )
g_element.attrib[SVG('height')] = str( height )
svg_doc.replace( layer_el, g_element )
It turned-out that the prefix
g_element.attrib[SVG('width')] = str( width )
in the width attribute is not required (the attribute itself is). Said prefix was causing Inkscape to strip the attribute from the document in a posterior post-processing step.