Closed viniciusccarvalho closed 2 years ago
Hey @viniciusccarvalho! i dont have any plans to add it to core however, there is a way to higlight some part of the editor since you control the higlighter function. If you want to see an example please checkout this repo : https://github.com/evwt/vue-tut
He also provided 2 live examples: scroll down to see highlighted code on the right.
Let me know if you need anything else :) Cheers!
Hi, refer to the vue-tut. I make a component to highlight line numbers. Hope the code below will be useful.
<template>
<v-card class="CodeDisplayer" rounded="lg">
<PrismEditor
class="CodeDisplayer-editor"
v-model="modelValueComputed"
:highlight="highlighter"
:readonly="readonly"
:tabSize="4"
line-numbers
ref="editor"
/>
<CopyButton :copy-content="modelValueComputed" class="CopyButton" />
</v-card>
</template>
<script setup lang="ts">
import { VCard } from 'vuetify/components';
import CopyButton from '../CopyButton/CopyButton.vue';
import { computed, onMounted, ref } from 'vue';
import { PrismEditor } from 'vue-prism-editor';
import 'vue-prism-editor/dist/prismeditor.min.css'; // import the styles somewhere
// import highlighting library (you can use any library you want just return html string)
import prismjs from 'prismjs';
// import { highlight, languages } from 'prismjs/components/prism-core';
import 'prismjs/themes/prism-tomorrow.css'; // import syntax highlighting styles
import 'prismjs/components/prism-clike';
import 'prismjs/components/prism-javascript';
import 'prismjs/components/prism-typescript';
import 'prismjs/components/prism-csharp';
import 'prismjs/components/prism-python';
interface IProps {
modelValue: string;
grammar: prismjs.Grammar;
language: string;
readonly?: boolean;
highlightLines?: Array<string | number>;
}
const props = withDefaults(defineProps<IProps>(), {
modelValue: '',
readonly: true,
highlightLines: () => [],
});
const emit = defineEmits(['update:modelValue']);
const modelValueComputed = computed({
get: () => props.modelValue,
set: (value) => emit('update:modelValue', value),
});
const highlighter = (code: string) => prismjs.highlight(code, props.grammar, props.language); // languages.<insert language> to return html with markup
// =================================================================================
// for line highlight
const editor = ref(undefined);
const $el = computed(() => (editor.value as any)?.$el as HTMLElement);
const GetLineEl = (lineNumber: number) =>
$el.value.querySelector(`.prism-editor__line-number:nth-child(${lineNumber + 1})`);
const Highlight = () => {
for (const highlightLine of props.highlightLines) {
if (typeof highlightLine === 'string') {
try {
const parse = (highlightLine || '').split('-').map((m) => parseInt(m));
HighlightLineRange(parse[0], parse[1]);
} catch (error) {
console.log('[Jctk.Vue3.Ext/CodeDisplayer] Invalid highlight range. Format should be start-end');
}
} else if (Number.isInteger(highlightLine)) {
HighlightLineNumber(highlightLine);
}
}
};
const HighlightLineNumber = (number: number) => {
let line = GetLineEl(number);
if (!line) {
return;
}
line.classList.add('highlight-line');
};
const HighlightLineRange = (start: number, end: number) => {
for (let idx = start; idx <= end; idx++) {
HighlightLineNumber(idx);
}
};
onMounted(() => {
Highlight();
});
// =================================================================================
</script>
<style scoped lang="scss">
.CodeDisplayer {
position: relative;
.CodeDisplayer-editor {
/* we dont use `language-` classes anymore so thats why we need to add background and text color manually */
background: #2d2d2d;
color: #ccc;
/* you must provide font-family font-size line-height. Example: */
font-family: Fira code, Fira Mono, Consolas, Menlo, Courier, monospace;
font-size: 14px;
line-height: 1.5;
padding-top: 12px;
padding-bottom: 12px;
}
.CopyButton {
position: absolute;
right: 0;
top: 0;
z-index: 1;
}
}
</style>
<style lang="scss">
// @import '../css/scrollbar.scss';
@import 'jctk.vue3.ext/src/css/scrollbar.scss';
/* required class */
.CodeDisplayer {
/* optional class for removing the outline */
.prism-editor__textarea:focus {
outline: none;
}
.prism-editor__editor {
white-space: pre !important;
}
.prism-editor__container {
overflow-x: scroll !important;
padding-bottom: 4px;
@include Scrollbar(14px, 8px);
}
// =================================================================================
// for line highlight
// $highlight-color-border: gray;
// $highlight-color: rgba(128, 128, 128, 0.384);
// $highlight-color-border: #42b983;
// $highlight-color: rgba(66, 185, 131, 0.165);
$highlight-color-border: #4e75a2;
$highlight-color: rgba(1, 115, 254, 0.22);
.prism-editor-wrapper {
overflow: hidden;
}
.prism-editor__line-numbers {
overflow: visible;
}
.prism-editor__line-number {
border-left: 5px solid transparent;
padding-left: 10px;
position: relative;
&.highlight-line {
border-left: 5px solid $highlight-color-border;
background: $highlight-color;
}
&.highlight-line:after {
content: '';
height: 21px;
background: $highlight-color;
pointer-events: none;
position: absolute;
z-index: 1;
width: 100vw;
}
}
// =================================================================================
}
</style>
Hi there, thanks for putting this up, pretty easy and amazing syntax highlighter for vue.
Is there a way to highlight a part of the editor, much like how github does when you pass a line information on viewing files?
Cheers