#include "ShellHighlighter.h" #include "Buffer.h" #include namespace kte { static void push(std::vector &out, int a, int b, TokenKind k){ if (b>a) out.push_back({a,b,k}); } void ShellHighlighter::HighlightLine(const Buffer &buf, int row, std::vector &out) const { const auto &rows = buf.Rows(); if (row < 0 || static_cast(row) >= rows.size()) return; std::string s = static_cast(rows[static_cast(row)]); int n = static_cast(s.size()); int i = 0; // if first non-space is '#', whole line is comment int bol = 0; while (bol < n && (s[bol]==' '||s[bol]=='\t')) ++bol; if (bol < n && s[bol] == '#') { push(out, bol, n, TokenKind::Comment); if (bol>0) push(out,0,bol,TokenKind::Whitespace); return; } while (i < n) { char c = s[i]; if (c == ' ' || c == '\t') { int j=i+1; while (j(c))) { int j=i+1; while (j(s[j]))||s[j]=='_')) ++j; std::string id=s.substr(i,j-i); static const char* kws[] = {"if","then","fi","for","in","do","done","case","esac","while","function","elif","else"}; bool kw=false; for (auto k: kws) if (id==k) { kw=true; break; } push(out,i,j, kw?TokenKind::Keyword:TokenKind::Identifier); i=j; continue; } if (std::ispunct(static_cast(c))) { TokenKind k = TokenKind::Operator; if (c=='('||c==')'||c=='{'||c=='}'||c==','||c==';') k=TokenKind::Punctuation; push(out,i,i+1,k); ++i; continue; } push(out,i,i+1,TokenKind::Default); ++i; } } } // namespace kte