编写主要模式:如何设置不同的起始字符串和结束字符串字符?

时间:2015-05-29 08:26:16

标签: emacs elisp

我正在编写一个主要模式,我可以使用这样的多行字符串:

Text : >abcde
fgh
ijklmonp<

其中'&gt;'和'&lt;'指示字符串的相应开始和结束。以下语法表条目仅标记&gt; ...&gt;和&lt; ...&lt;字符串,这不是我想要的。

(modify-syntax-entry ?> "\"" st)
(modify-syntax-entry ?< "\"" st)

目前最好的解决方案是使用通用字符串分隔符:'|',但它仍然会弄乱我的系统,因为我有&gt; ...&lt; ...&lt;有时情况。如果我可以使用像

这样的多行正则表达式,那将是最好的
^Text : >.*<$

我怎样才能做到这一点?

2 个答案:

答案 0 :(得分:1)

正如thornjad所解释的那样,语法表不直接支持此功能,因此您需要使用 <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.1.8.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>5.1.8.RELEASE</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.0.0.Final</version> <type>pom</type> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-c3p0</artifactId> <version>5.0.0.Final</version> <type>pom</type> </dependency> <dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>0.9.5.4</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.10.0.pr1</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.0.0.Final</version> </dependency> <dependency> <groupId>javax.servlet.jsp.jstl</groupId> <artifactId>javax.servlet.jsp.jstl-api</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>2.3.3</version> </dependency> <dependency> <groupId>hsqldb</groupId> <artifactId>hsqldb</artifactId> <version>1.8.0.10</version> </dependency> </dependencies> 。例如

package com.springimplant.config;

import java.util.Properties;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScans;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import static org.hibernate.cfg.Environment.*;

@Configuration
@PropertySource("classpath:db.properties")
@EnableTransactionManagement
@ComponentScans(value= {
        @ComponentScan("com.springimplant.dao"),
        @ComponentScan("com.springimplant.service")
})
public class AppConfig {

    @Autowired
    private Environment env;

    @Bean
    public LocalSessionFactoryBean getSessionFactory()
    {
        LocalSessionFactoryBean factoryBean=new LocalSessionFactoryBean();
        Properties props=new Properties();

        //Setting JDBC Properties
        props.put(DRIVER,env.getProperty("mysql.driver"));
        props.put(URL,env.getProperty("mysql.url"));
        props.put(USER,env.getProperty("mysql.user"));
        props.put(PASS,env.getProperty("mysql.password"));

        //Setting Hibernate Properties
        props.put(SHOW_SQL,env.getProperty("hibernate.show_sql"));
        props.put(HBM2DDL_AUTO,env.getProperty("hibernate.hbm2ddl.auto"));

        //Setting c3P0 properties
        props.put(C3P0_MIN_SIZE,env.getProperty("hibernate.c3p0.min_size"));
        props.put(C3P0_MAX_SIZE,env.getProperty("hibernate.c3p0.max_size"));
        props.put(C3P0_ACQUIRE_INCREMENT,env.getProperty("hibernate.c3p0.acquire_increment"));
        props.put(C3P0_TIMEOUT,env.getProperty("hibernate.c3p0.timeout"));
        props.put(C3P0_MAX_STATEMENTS,env.getProperty("hibernate.c3p0.max_statements"));

        factoryBean.setHibernateProperties(props);
        factoryBean.setPackagesToScan("com.springimplant.model");

        return factoryBean;
    }

    @Bean
    public HibernateTransactionManager getTransactionManager()
    {
        HibernateTransactionManager transactionManager= new HibernateTransactionManager();
        transactionManager.setSessionFactory(getSessionFactory().getObject());
        return transactionManager;
    }
}

然后在您的主要模式功能中:

syntax-propertize-function

(defconst my-syntax-propertize (syntax-propertize-rules (">" (0 (unless (nth 8 (save-excursion (syntax-ppss (match-beginning 0))) (string-to-syntax "|")))) ("<" (0 (when (eq t (nth 3 (save-excursion (syntax-ppss (match-beginning 0)))) (string-to-syntax "|")))))) 测试可确保仅将(setq-local syntax-propertize-function my-syntax-propertize) 标记为字符串定界符(如果它不在另一个字符串或注释中),而nth 8测试可确保>仅在由另一个通用字符串定界符启动的字符串出现时,才被标记为字符串定界符。

答案 1 :(得分:0)

不幸的是,modify-syntax-entry的功能不足以应付这种情况。幸运的是,我们还有其他选择!我的orson-mode处理了一个类似的问题,即字符串用双引号('')而不是双引号(")分隔。

为此,一个正则表达式将查找整个字符串,包括引号,然后使用Emacs的string-fence类将引号标记为围栏。

(defconst orson--string-rx
  "\\(''[^']*''\\)")

(defun orson-syntax-propertize-function (start end)
  (save-excursion
    (goto-char start)
    (while (re-search-forward orson--string-rx end 'noerror)
      (let ((a (match-beginning 1))
            (b (match-end 1))
            (string-fence (string-to-syntax "|")))
        (put-text-property a (1+ a) 'syntax-table string-fence)
        (put-text-property (1- b) b 'syntax-table string-fence))))